# cookiecutter-uv: a Python project skeleton where the tooling is already decided

> cookiecutter-uv is a Cookiecutter template that generates a Python project with uv for dependencies, ruff, mypy or ty, deptry, pre-commit, pytest, tox-uv, GitHub Actions, a devcontainer and PyPI publishing already configured. The value is not the code it produces, it is the set of decisions it has already made for you.

**osprey-oss/cookiecutter-uv** — A modern cookiecutter template for Python projects that use uv for dependency management 

- Repository: https://github.com/osprey-oss/cookiecutter-uv
- Website: https://osprey-oss.github.io/cookiecutter-uv
- Stars: 1,340 · Forks: 190
- Language: Python
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/osprey-oss-cookiecutter-uv

## The template ships decisions, not just files

cookiecutter-uv is described as a modern Cookiecutter template that can be used to initiate a Python project with all the necessary tools for development, testing and deployment.

The feature list is the argument. uv for dependency management, and support for both the src layout and the flat layout, which is a decision many teams agonise over and then have to apply consistently. CI/CD with GitHub Actions. Pre-commit hooks with pre-commit. Code quality with ruff, with mypy or ty, and with deptry for finding obsolete dependencies. Publishing to PyPI by creating a new release on GitHub, so the release process is a tag rather than a ritual. Testing and coverage with pytest and codecov. Documentation with MkDocs or Zensical. Compatibility testing across Python versions with tox-uv. Containerization with Docker or Podman. A development environment with VSCode devcontainers.

Read as a list, that is a fairly complete answer to the question every new Python project asks, which is what tooling do I install and how do I wire them together. The alternative is a day of reading documentation and copying configuration between repositories, and the value of the template is that the wiring is already known to work together, which is not something you can infer from a list of individual tools.

The project is MIT licensed, supports Python 3.10 through 3.14, and the documentation lives at osprey-oss.github.io/cookiecutter-uv. The last push to the repository was on 2026-10-10, and the recent releases are 0.0.12 from April 2026, 0.0.11 from July 2025 and 0.0.10 from May 2025.

## The template is a package, and the generated project is a directory of braces

The repository layout explains how Cookiecutter templates are put together, and this one is no exception. The generated project lives in a directory literally named {{cookiecutter.project_name}}, which is how Cookiecutter marks the directory it renames and fills in. The prompts that drive that process are in cookiecutter.json, and the hooks directory holds the pre- and post-generation scripts.

The interesting part is that the template is also a working Python package. There is a cookiecutter_uv directory, and the project metadata declares it as such, with a console script named cookiecutter-uv-cicd pointing at cookiecutter_uv.cicd.cli:cli. So the repository ships a small tool of its own, separate from the template it generates, and the script entry point is described in the feature list as CI/CD with GitHub Actions.

The rest of the layout is what you would expect from a maintained template. There is a docs directory with the documentation site, a static directory for assets, a tests directory, a tox.ini, a uv.lock, a zensical.toml for the documentation tool, a .devcontainer directory, a .pre-commit-config.yaml, a MANIFEST.in and a Makefile.

The pyproject file is worth a look because it says what the template itself depends on, and it is a short list: click and cookiecutter, with a build backend of hatchling. The development group is longer, with pytest, pre-commit, pytest-cookies for testing generated projects, tox-uv, deptry, mypy, pytest-cov, ruff, mkdocstrings-python, zensical and tomli. The pytest configuration points at a tests directory and declares a slow marker, which is how the generated projects are tested rather than the template code alone.

## One command generates, and the generated README takes over

The quickstart is two commands, and the second one is the fallback for anyone without uv.

On your local machine, navigate to the directory in which you want to create a project directory, and run:

```bash
uvx cookiecutter https://github.com/osprey-oss/cookiecutter-uv.git
```

Or if you do not have uv installed yet:

```bash
pip install cookiecutter
cookiecutter https://github.com/osprey-oss/cookiecutter-uv.git
```

You follow the prompts to configure the project, and once it completes, a new directory containing the project is created. Then you navigate into that directory and follow the instructions in the README.md to complete the setup.

That last sentence is the design in miniature. The template is not supposed to be finished when the generator stops. The generated README carries the remaining setup, which is the part that differs per project, and the generated project is expected to be a starting point that you then own.

The choice of uvx for the primary path is a small but meaningful signal. It runs the template in an ephemeral environment, so nothing is installed into your system Python and there is no version of cookiecutter to keep in step with the template's own expectations.

## The check target is the part that makes the template worth using

The Makefile shows how the maintainers work on the template, and the check target is the interesting one.

```bash
@uv lock --locked
@uv run pre-commit run -a
@uv run mypy
@uv run deptry .
```

Those four lines are a quality gate. uv lock --locked checks that the lock file is consistent with pyproject.toml and fails if it is not, which is the check that catches a dependency edited without the lock file being refreshed. pre-commit run -a runs the hooks across the repository, which is where formatting and lint rules are enforced. mypy does the static type checking. And deptry . checks for obsolete dependencies, which is a category of problem that quietly accumulates in a project that has been running for a year.

The rest of the Makefile is the ordinary lifecycle. The bake targets generate a project from the template itself, which is dogfooding: bake runs cookiecutter with --no-input and --overwrite-if-exists, bake-src does the same with layout set to src, and bake-with-inputs runs it with the prompts. The install target runs uv sync, test runs pytest with coverage, build produces a wheel with pyproject-build through uvx, publish uploads with twine, and build-and-publish chains the two. There is also a docs-test target that checks the documentation builds without warnings or errors.

The bake targets are the part most templates do not have. Generating the template with itself, in both layouts, is how you catch a template that only works for the configuration its author happened to use.

## It descends from cookiecutter-pypackage, and the difference is the toolchain

The README credits its own ancestry: the project is partially based on Audrey Feldroy's cookiecutter-pypackage repository.

That relationship is the clearest way to state the difference in approach. The ancestor is a general purpose Python package template built around the conventional packaging tooling, and this one keeps the shape and swaps the toolchain underneath it. uv replaces pip and a separate lock file, ruff and mypy or ty and deptry form the quality gate, tox-uv handles multi-version testing, Zensical is offered alongside MkDocs for documentation, and GitHub Actions with a release-triggered publish flow replaces whatever the original used.

For a team that has already standardised on the older template and is happy with it, the change is not compelling and the churn is not worth it. For a team starting fresh in 2026 and expecting to work with uv, the difference is most of the work of a project setup.

The other alternative is to skip templates entirely and copy from a previous project. That approach has one real advantage, which is that you inherit a configuration you already trust, and one large drawback, which is that the configuration you inherit is the configuration you had, including the parts that were wrong. A template is a chance to take the current best practice rather than the current state of your own repository.

## The documentation links still point at the old organisation

There is a small inconsistency in the metadata that is worth knowing about before you go looking for the documentation.

The README's badges and links point at osprey-oss.github.io/cookiecutter-uv, and the documentation link in the quickstart section is the same. But the project URLs in the pyproject metadata list the documentation and the homepage as fpgmaas.github.io/cookiecutter-uv, and the docs badge in the README header also points at fpgmaas. The author in the metadata is Florian Maas, with the email fpgmaas@gmail.com, and the project lives under the osprey-oss organisation.

So the project appears to have moved from a personal namespace to an organisation, with the metadata in pyproject.toml and part of the README not updated to match. The repository URL in the same metadata block is correct, pointing at github.com/osprey-oss/cookiecutter-uv, and the documentation URLs are the only stale entries in the file.

The practical effect is that one of the two documentation URLs will work and the other will not, and which one depends on where you click. Both are hosted on GitHub Pages, so a stale path gives a 404 rather than a redirect, and the working link in the README body is the one to trust.

It is a small thing, and the kind of thing that is a symptom of a project that is being maintained by people doing real work rather than by a release process. The version is 0.0.12 and the classifier is Development Status :: 4 - Beta, so the template is still pre-1.0 and the URLs are part of the same story.

## Conclusion

cookiecutter-uv fits a developer starting a new Python package who wants uv, a linter, a type checker and a CI pipeline set up in the first minute rather than the first week. It does not fit a project that already has its own opinions about layout, tooling or publishing, and the dependency set it pins moves quickly enough that the generated lock file is worth regenerating. Before you use it, read the generated README, check the pins in uv.lock against what you actually want, and note that the template itself is still at a 0.x version.

## FAQ

### How do I generate a project from cookiecutter-uv?

Run uvx cookiecutter https://github.com/osprey-oss/cookiecutter-uv.git from the directory where you want the new project, then follow the prompts. If you do not have uv installed, use pip install cookiecutter followed by cookiecutter with the same URL, and afterwards follow the instructions in the generated README.

### Which Python versions does cookiecutter-uv support?

The README badge lists Python 3.10, 3.11, 3.12, 3.13 and 3.14, and the template's own pyproject declares requires-python as >=3.10,<4.0 with classifiers for the same versions.

### What does the cookiecutter-uv check target run?

The check target runs uv lock --locked to confirm the lock file matches pyproject.toml, then pre-commit run -a, then mypy for static type checking, and then deptry . to look for obsolete dependencies.

### Can I choose a src layout instead of a flat one?

Yes. The template supports both the src and flat layouts, and the Makefile has a bake-src target that generates a project with layout set to src, alongside the default bake target.

### How is cookiecutter-uv published to PyPI?

The feature list says publishing to PyPI happens by creating a new release on GitHub, and the template includes GitHub Actions for CI/CD. The template's own Makefile has publish and build-and-publish targets that build a wheel and upload it with twine.

## Sources

- [License: MIT](https://github.com/osprey-oss/cookiecutter-uv/blob/main/LICENSE)
- [osprey-oss/cookiecutter-uv on GitHub](https://github.com/osprey-oss/cookiecutter-uv)
- [Project website](https://osprey-oss.github.io/cookiecutter-uv)
- [README](https://github.com/osprey-oss/cookiecutter-uv/blob/main/README.md)
- [Releases](https://github.com/osprey-oss/cookiecutter-uv/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/osprey-oss-cookiecutter-uv
