Skip to content

feat: add uv backend #618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/reusable-cookie.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ jobs:
- name: Test flit
run: nox -s 'tests(flit, novcs)' -s 'tests(flit, vcs)'

- name: Test uv
run: nox -s 'tests(uv, novcs)'

- name: Test pdm
run: nox -s 'tests(pdm, novcs)' -s 'tests(pdm, vcs)'

Expand Down
48 changes: 26 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,32 @@ hand, from `{{cookiecutter.project_name}}/`).

During generation you can select from the following backends for your package:

1. [hatch][]: This uses hatchling, a modern builder with nice file inclusion,
extendable via plugins, and good error messages. **(Recommended for pure
Python projects)**
2. [flit][]: A modern, lightweight [PEP 621][] build system for pure Python
projects. Replaces setuptools, no MANIFEST.in, setup.py, or setup.cfg. Low
learning curve. Easy to bootstrap into new distributions. Difficult to get
the right files included, little dynamic metadata support.
3. [pdm][]: A modern, less opinionated all-in-one solution to pure Python
projects supporting standards. Replaces setuptools, venv/pipenv, pip, wheel,
and twine. Supports [PEP 621][].
4. [poetry][]: An all-in-one solution to pure Python projects. Replaces
setuptools, venv/pipenv, pip, wheel, and twine. Higher learning curve, but is
all-in-one. Makes some bad default assumptions for libraries.
5. [setuptools][]: The classic build system, but with the new standardized
configuration.
6. [pybind11][]: This is setuptools but with an C++ extension written in
[pybind11][] and wheels generated by [cibuildwheel][].
7. [scikit-build][]: A scikit-build (CMake) project also using pybind11, using
scikit-build-core. **(Recommended for C++ projects)**
8. [meson-python][]: A Meson project also using pybind11. (No VCS versioning)
9. [maturin][]: A [PEP 621][] builder for Rust binary extensions. (No VCS
versioning) **(Recommended for Rust projects)**
1. [hatch][]: This uses hatchling, a modern builder with nice file inclusion,
extendable via plugins, and good error messages. **(Recommended for pure
Python projects)**
2. [uv][]: The `uv_build` backend is written in Rust and is integrated into'
`uv`, meaning it can build without downloading anything extra and can even
avoid running Python at all when building, making it the fastest backend for
simple packages. No dynamic metadata support.
3. [flit][]: A modern, lightweight [PEP 621][] build system for pure Python
projects. Replaces setuptools, no MANIFEST.in, setup.py, or setup.cfg. Low
learning curve. Easy to bootstrap into new distributions. Difficult to get
the right files included, little dynamic metadata support.
4. [pdm][]: A modern, less opinionated all-in-one solution to pure Python
projects supporting standards. Replaces setuptools, venv/pipenv, pip, wheel,
and twine. Supports [PEP 621][].
5. [poetry][]: An all-in-one solution to pure Python projects. Replaces
setuptools, venv/pipenv, pip, wheel, and twine. Higher learning curve, but
is all-in-one. Makes some bad default assumptions for libraries.
6. [setuptools][]: The classic build system, but with the new standardized
configuration.
7. [pybind11][]: This is setuptools but with an C++ extension written in
[pybind11][] and wheels generated by [cibuildwheel][].
8. [scikit-build][]: A scikit-build (CMake) project also using pybind11, using
scikit-build-core. **(Recommended for C++ projects)**
9. [meson-python][]: A Meson project also using pybind11. (No VCS versioning)
10. [maturin][]: A [PEP 621][] builder for Rust binary extensions. (No VCS
versioning) **(Recommended for Rust projects)**

Currently, the best choice is probably hatch for pure Python projects, and
scikit-build (such as the scikit-build-core + pybind11 choice) for binary
Expand Down
4 changes: 3 additions & 1 deletion cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"license": ["BSD", "Apache", "MIT"],
"backend": [
"hatch",
"uv",
"flit",
"pdm",
"poetry",
Expand All @@ -34,14 +35,15 @@
"backend": {
"__prompt__": "Choose a build backend",
"hatch": "Hatchling - Pure Python (recommended)",
"uv": "uv_build - Pure Python (fast)",
"flit": "Flit-core - Pure Python (minimal)",
"pdm": "PDM-backend - Pure Python",
"poetry": "Poetry - Pure Python",
"setuptools": "Setuptools - Pure Python",
"pybind11": "Setuptools and pybind11 - Compiled C++",
"skbuild": "Scikit-build-core - Compiled C++ (recommended)",
"mesonpy": "Meson-python - Compiled C++ (also good)",
"maturin": "Maturin - Compiled Rust (recommended)"
"maturin": "Maturin - Compiled Rust (recommended)"
},
"vcs": "Use version control for versioning"
}
Expand Down
1 change: 1 addition & 0 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ backend:
help: Choose a build backend
choices:
"Hatchling - Pure Python (recommended)": hatch
"uv_build - Pure Python (fast)": uv
"Flit-core - Pure Python (minimal)": flit
"PDM-backend - Pure Python": pdm
"Poetry - Pure Python": poetry
Expand Down
10 changes: 9 additions & 1 deletion docs/pages/guides/packaging_simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,19 @@ requires = ["hatchling"]
build-backend = "hatchling.build"
```

{% endtab %} {% tab uv uv_build %}

```toml
[build-system]
requires = ["uv_build>=0.7.19"]
build-backend = "uv_build"
```

{% endtab %} {% tab flit Flit-core %}

```toml
[build-system]
requires = ["flit_core>=3.3"]
requires = ["flit_core>=3.12"]
build-backend = "flit_core.buildapi"
```

Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def rmtree_ro(path: Path) -> None:


def get_expected_version(backend: str, vcs: bool) -> str:
return "0.2.3" if vcs and backend not in {"maturin", "mesonpy"} else "0.1.0"
return "0.2.3" if vcs and backend not in {"maturin", "mesonpy", "uv"} else "0.1.0"


def make_copier(session: nox.Session, backend: str, vcs: bool) -> None:
Expand Down
7 changes: 5 additions & 2 deletions {{cookiecutter.project_name}}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{%- if cookiecutter.backend == "pdm" %}
requires = ["pdm-backend>=2.4"]
build-backend = "pdm.backend"
{%- elif cookiecutter.backend == "uv" %}
requires = ["uv_build>=0.7.19"]
build-backend = "uv_build"
{%- elif cookiecutter.backend == "maturin" %}
requires = ["maturin>=1.9,<2"]
build-backend = "maturin"
Expand Down Expand Up @@ -53,7 +56,7 @@ build-backend = "poetry.core.masonry.api"

[project]
name = "{{ cookiecutter.project_name }}"
{%- if cookiecutter.backend in ['maturin', 'mesonpy'] or not cookiecutter.vcs and cookiecutter.backend in ['setuptools', 'pybind11', 'skbuild', 'poetry'] %}
{%- if cookiecutter.backend in ['maturin', 'mesonpy', 'uv'] or not cookiecutter.vcs and cookiecutter.backend in ['setuptools', 'pybind11', 'skbuild', 'poetry'] %}
version = "0.1.0"
{%- endif %}
authors = [
Expand Down Expand Up @@ -102,7 +105,7 @@ classifiers = [
"Topic :: Scientific/Engineering",
"Typing :: Typed",
]
{%- if cookiecutter.backend not in ['maturin', 'mesonpy'] and cookiecutter.vcs or cookiecutter.backend in ['pdm', 'hatch', 'flit'] %}
{%- if cookiecutter.backend not in ['maturin', 'mesonpy', 'uv'] and cookiecutter.vcs or cookiecutter.backend in ['pdm', 'hatch', 'flit'] %}
dynamic = ["version"]
{%- endif %}
dependencies = []
Expand Down
Loading