From hyperskills
Configures uv-build as Rust-based backend for pure Python packages, sets up pyproject.toml for fast in-process builds, module discovery, and PyPI publishing without Python.
npx claudepluginhub hyperb1iss/hyperskills --plugin hyperskillsThis skill uses the workspace's default tool permissions.
`uv_build` is Astral's Rust-based build backend for Python packages. As of uv-build 0.11.11 (May 2026), it is the native backend documented by uv for most pure Python packages. **Pure Python packages only:** no C/Rust extensions.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
uv_build is Astral's Rust-based build backend for Python packages. As of uv-build 0.11.11 (May 2026), it is the native backend documented by uv for most pure Python packages. Pure Python packages only: no C/Rust extensions.
Is your package pure Python?
├─ YES → Needs VCS versioning, build hooks, or dynamic metadata?
│ ├─ NO → uv_build (fast, zero-config, excellent defaults)
│ └─ YES → hatchling (extensible, plugin ecosystem)
└─ NO → What kind of extensions?
├─ Rust (PyO3) → maturin
├─ C/C++ (CMake) → scikit-build-core
└─ C/C++ (classic) → setuptools
Migration blocker: dynamic = [...] is not supported. Projects using dynamic = ["version"] with hatchling/setuptools must switch to static versions in pyproject.toml (use uv version --bump for version management).
[build-system]
requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build"
For published packages and CI, prefer an upper bound such as <0.12 so new minor releases are adopted deliberately after uv build verification.
When uv detects uv_build as the backend, it bypasses PEP 517 entirely, calling directly into Rust code in-process. No Python subprocess, no build environment creation, no dependency installation.
This means you can build and publish packages without Python installed, the entire build runs in Rust.
Conditions for fast path:
build-backend is exactly "uv_build"requires contains only uv_build (no extra build deps)Force PEP 517 mode: uv build --force-pep517
Default: expects src/<package_name>/__init__.py (src layout).
[tool.uv.build-backend]
module-root = "src" # Default (src layout)
module-root = "" # Flat layout (package at project root)
module-name = "my_package" # Override auto-detected name
[tool.uv.build-backend]
module-name = ["foo", "bar"]
[tool.uv.build-backend]
module-name = "cloud.database" # Dotted name — parent must NOT have __init__.py
For multiple namespace roots:
[tool.uv.build-backend]
namespace = true
module-name = ["cloud.database", "cloud.auth"]
Auto-detected from -stubs suffix in package name. Uses __init__.pyi instead of __init__.py.
[tool.uv.build-backend]
source-include = ["tests/**", "CHANGELOG.md"] # Extra files for sdist
source-exclude = ["*.bin", "benchmarks/**"] # Exclude from sdist AND wheel
wheel-exclude = ["tests/**"] # Exclude from wheel only
default-excludes = true # __pycache__, *.pyc (default on)
Patterns: PEP 639 portable glob syntax. Exclusions always override inclusions.
Safety features:
.venv or node_modules)pyproject.toml + module source always included regardless of patternsuv build --list # Show what would be included (no actual build)
[tool.uv.build-backend.data]
scripts = "bin" # -> <venv>/bin (executables)
headers = "include/mylib" # -> include dir (C headers)
data = "share" # -> venv root (careful: can overwrite!)
uv build # Build sdist + wheel to dist/
uv build --sdist # Source distribution only
uv build --wheel # Wheel only
uv build --list # Preview included files
uv build --no-sources # Test PyPI compatibility (strips tool.uv.sources)
uv build --package <name> # Specific workspace member
uv build --build-constraints c.txt # Pin build dependency versions
uv build --require-hashes # Hash verification for build deps
uv build --force-pep517 # Bypass fast path
uv version # Check current
uv version --bump minor # 1.0.0 -> 1.1.0
uv version --bump patch --dry-run # Preview
uv build # Build
uv publish # Upload to PyPI
uv publish --check-url https://pypi.org/simple/ # Skip if already published
[project]
classifiers = ["Private :: Do Not Upload"]
uv_build uses static .pth files for editable installs (not dynamic import hooks like setuptools). This works correctly with type checkers and IDEs out of the box, no editable_mode = "compat" workaround needed.
uv sync # Installs project as editable by default
uv pip install -e . # Explicit editable install
uv_build is strict about metadata:
project.description with newlinesproject.scripts/project.gui-scripts)No dynamic metadata: dynamic = [...] is not supported. All metadata must be static in pyproject.toml.
[project]
name = "cloud-database"
version = "2.1.0"
description = "Cloud database toolkit"
readme = "README.md"
license = "MIT"
requires-python = ">=3.10"
dependencies = ["sqlalchemy>=2.0"]
[project.scripts]
cloud-db = "cloud_database.cli:main"
[build-system]
requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build"
[tool.uv.build-backend]
source-include = ["tests/**", "CHANGELOG.md"]
wheel-exclude = ["tests/**"]
Prerequisites: Pure Python, all metadata in [project] table (PEP 621), no setup.py build logic.
# BEFORE
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
# AFTER
[build-system]
requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build"
MANIFEST.in equivalents:
| MANIFEST.in | uv_build |
|---|---|
include CHANGELOG.md | source-include = ["CHANGELOG.md"] |
recursive-include tests | source-include = ["tests/**"] |
global-exclude *.pyc | Handled by default-excludes |
prune docs | source-exclude = ["docs/**"] |
# BEFORE
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# AFTER
[build-system]
requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build"
Blockers: VCS versioning ([tool.hatch.version]), build hooks ([tool.hatch.build.hooks.*]).
# BEFORE
[build-system]
requires = ["flit_core>=3.4"]
build-backend = "flit_core.buildapi"
# AFTER (flit uses flat layout by default)
[build-system]
requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build"
[tool.uv.build-backend]
module-root = ""
uv build --list # Check included files match expectations
uv build # Build and inspect artifacts
uv build --no-sources # Verify PyPI compatibility
| Limitation | Impact | Alternative |
|---|---|---|
| Pure Python only | No C/C++/Cython/Rust extensions | setuptools, maturin, scikit-build-core |
| No dynamic metadata | Can't derive version from VCS/git tags | hatchling + hatch-vcs, or uv version --bump |
| No build hooks | No code gen, protobuf, asset bundling | hatchling with build hooks |
| No setup.py/setup.cfg | Must fully convert to pyproject.toml | Convert first, then migrate |
| Upper-bound pinning | Must update requires when upgrading | Manageable with uv version workflow |
| Anti-Pattern | Fix |
|---|---|
| Using uv_build for packages with C extensions | Use setuptools, maturin, or scikit-build-core |
| Unbounded backend in CI/published packages | Use a tested minor range and bump deliberately |
source-include = ["**/*"] | Let defaults handle it; add specific patterns only |
Forgetting --no-sources test before publish | Sources are dev-only; verify PyPI-only resolution works |
Dynamic version from __init__.py | Static version in pyproject.toml + uv version --bump |