
Uv Build
- 17 installs
- 25 repo stars
- Updated July 31, 2026
- hyperb1iss/hyperskills
Configures uv_build as the build backend for pure-Python packages, producing sdists and wheels and publishing to PyPI.
About
Covers building and publishing pure-Python packages with Astral's Rust-based uv_build backend. A developer uses it to configure a pyproject.toml build-system, produce sdist/wheel, or publish to PyPI.
- Zero-config backend for pure-Python packages
- Decision tree pointing to hatchling when hooks/dynamic metadata needed
Uv Build by the numbers
- 17 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #190 of 290 Python skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hyperb1iss/hyperskills --skill uv-buildAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 17 |
|---|---|
| repo stars | ★ 25 |
| Last updated | July 31, 2026 |
| Repository | hyperb1iss/hyperskills ↗ |
What it does
Configures uv_build as the build backend for pure-Python packages, producing sdists and wheels and publishing to PyPI.
Files
uv-build: Python Build Backend
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.
When to Use uv-build
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) → setuptoolsMigration 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).
Setup
[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.
The Direct Build Fast Path
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-backendis exactly"uv_build"requirescontains onlyuv_build(no extra build deps)- Version specifier is within known compatible range
Force PEP 517 mode: uv build --force-pep517
Module Discovery
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 nameMultiple Modules
[tool.uv.build-backend]
module-name = ["foo", "bar"]Namespace Packages (PEP 420)
[tool.uv.build-backend]
module-name = "cloud.database" # Dotted name — parent must NOT have __init__.pyFor multiple namespace roots:
[tool.uv.build-backend]
namespace = true
module-name = ["cloud.database", "cloud.auth"]Type Stub Packages
Auto-detected from -stubs suffix in package name. Uses __init__.pyi instead of __init__.py.
File Inclusion/Exclusion
[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:
- Warns on 10k+ files (likely traversing
.venvornode_modules) - Detects virtual environments and skips them
pyproject.toml+ module source always included regardless of patterns
Preview Included Files
uv build --list # Show what would be included (no actual build)Wheel Data Directories
[tool.uv.build-backend.data]
scripts = "bin" # -> <venv>/bin (executables)
headers = "include/mylib" # -> include dir (C headers)
data = "share" # -> venv root (careful: can overwrite!)Build Commands
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 pathPublishing Workflow
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 publishedPrevent Accidental Publication
[project]
classifiers = ["Private :: Do Not Upload"]Editable Installs
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 installMetadata Validation
uv_build is strict about metadata:
- Rejects
project.descriptionwith newlines - Enforces SPDX license expressions
- Validates classifiers
- Rejects non-UTF-8 READMEs
- Blocks reserved entrypoint groups (must use
project.scripts/project.gui-scripts)
No dynamic metadata: dynamic = [...] is not supported. All metadata must be static in pyproject.toml.
Complete Example
[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/**"]Migration from Other Backends
From setuptools
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/**"] |
From hatchling
# 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.*]).
From flit
# 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 = ""Verification
uv build --list # Check included files match expectations
uv build # Build and inspect artifacts
uv build --no-sources # Verify PyPI compatibilityLimitations
| 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-Patterns
| 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 |
What This Skill is NOT
- Not for building C/Rust/Cython extensions
- Not for projects requiring VCS-derived versioning
- Not for complex build pipelines needing hooks
- Not a uv project management guide (see uv skill)