A cookiecutter template for modern Python libraries with:
uvfor environment and dependency management- PEP 621 metadata in
pyproject.toml src/package layout- Ruff, Pytest, pre-commit, and GitHub Actions
- starter docs for both maintainers and new contributors
Install the two tools you need:
uv tool install cookiecutterGenerate a new project:
cookiecutter https://github.com/HenriquesLab/PythonPackageCookiecutterEnter the generated project and bootstrap it with uv:
cd your-project-name
uv sync
uv run pre-commit install
uv run pytestEach generated project includes:
pyproject.tomlconfigured for modern packaging anduv.python-versionfor a pinned local interpreter targetREADME.mdwith a project overview and key commandsGETTING_STARTED.mdwith a minimal setup guide and command explanationsCONTRIBUTING.mdwith a contributor workflowmakefilewith commonuv-powered shortcutsruff.tomland.pre-commit-config.yamlfor code quality- a simple GitHub Actions workflow
src/andtests/starter structure
your-project/
├── .github/workflows/ci.yml
├── .python-version
├── .editorconfig
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GETTING_STARTED.md
├── LICENSE.txt
├── makefile
├── pyproject.toml
├── README.md
├── ruff.toml
├── src/
│ └── your_package/
│ ├── __init__.py
│ └── your_module.py
└── tests/
└── test_your_class.py
When you run Cookiecutter, you will be prompted for:
author_name: maintainer name for package metadataauthor_email: maintainer contact emaildirectory_name: repository and top-level folder namefile_name: starter module filename inside the packagepackage_name: import/package nameclass_name: example class used by the starter code and testdescription: short project descriptionrepository_url: canonical repository URL used in package metadataminimum_python_version: minimum supported Python versionlicense: SPDX license expression used in package metadata andLICENSE.txt
The pre-generation hook validates package_name so it stays compatible with common Python packaging conventions.
The template is designed around uv:
uv sync
uv run pytest
uv run ruff check .
uv run ruff format .
uv run python -m buildIf you prefer short aliases, the generated makefile wraps the same commands:
make sync
make test
make lint
make format
make buildRepo-level documentation:
Generated-project documentation:
README.mdfor the project overviewGETTING_STARTED.mdfor first-time setupCONTRIBUTING.mdfor the contributor workflow
To update the template, edit files under {{cookiecutter.directory_name}}/ and keep the repository docs aligned with the generated docs. The licenses/ directory is only a temporary template asset and is removed automatically by the post-generation hook.
This repository contains the template itself. Generated projects can choose one of the bundled license options, and the matching LICENSE.txt will be included automatically.