Open-Source Wikis

/

uv

/

uv

/

Architecture

astral-sh/uv

Architecture

uv is a Cargo workspace of ~70 crates that together implement a Python package and project manager. The top-level binary uv is a thin CLI shell that delegates almost all behavior to focused library crates. This page sketches the layout, the major subsystems, and how a typical uv invocation flows through them.

Workspace layout

astral-sh/uv
├── crates/
│   ├── uv/                   # The `uv` binary: argument dispatch, command implementations
│   ├── uv-cli/               # Clap-based argument schema (8000+ lines of derive types)
│   ├── uv-settings/          # Resolved settings model (pyproject + uv.toml + env + CLI)
│   ├── uv-configuration/     # Build, resolution, install configuration enums
│   ├── uv-resolver/          # PubGrub-based universal resolver and lockfile
│   ├── uv-installer/         # Plan + install wheels into a virtualenv
│   ├── uv-install-wheel/     # Low-level wheel layout and unpacking
│   ├── uv-python/            # Interpreter discovery, managed Python, downloads
│   ├── uv-virtualenv/        # `python -m venv` replacement
│   ├── uv-client/            # Cached HTTP client for PyPI-compatible registries
│   ├── uv-cache/             # Filesystem cache layout and locking
│   ├── uv-distribution/      # Fetching metadata for wheels and sdists
│   ├── uv-distribution-types/# Distribution / index / requirement types
│   ├── uv-distribution-filename/# Wheel and sdist filename parsing
│   ├── uv-build-frontend/    # PEP 517 build frontend (calls into a backend in a venv)
│   ├── uv-build-backend/     # uv's own PEP 517 build backend (`uv_build`)
│   ├── uv-workspace/         # `pyproject.toml` parsing, workspace discovery
│   ├── uv-pep440/            # PEP 440 versions and specifiers
│   ├── uv-pep508/            # PEP 508 requirements and markers
│   ├── uv-pypi-types/        # Wire types shared with PyPI APIs
│   ├── uv-tool/              # `uv tool` / `uvx` — tool installation
│   ├── uv-publish/           # `uv publish` — upload to PyPI/PyPI-like indexes
│   ├── uv-auth/              # Credentials cache, keyring, trusted publishing
│   ├── uv-keyring/           # Keyring provider implementations
│   ├── uv-git/               # Git source distribution support
│   ├── uv-scripts/           # PEP 723 inline-metadata scripts
│   ├── uv-requirements*      # Requirements.txt parsing and project requirements
│   ├── uv-trampoline*        # Windows console-script trampolines
│   ├── uv-bin-install/       # `uv self update`-style bootstrap helpers
│   ├── uv-fs/                # Filesystem helpers, locked files, `simplified` paths
│   ├── ...                   # Many small focused crates (see crates/index.md)
├── docs/                     # mkdocs source for the user docs
├── scripts/                  # Maintenance, benchmarking, packaging scripts
├── test/                     # Test fixtures (workloads for resolver/installer benchmarks)
├── python/                   # The PyPI distribution shell (build backend wiring)
└── crates/uv-trampoline/     # Nightly-only no_std crate, excluded from main workspace

Crates are versioned together (0.0.41 for libraries, 0.11.x for the user-facing uv crate). Astral explicitly considers the workspace members internal API and reserves the right to break them between releases, even though they are published to crates.io.

Major subsystems

uv groups its functionality into a handful of subsystems. The crates lens maps every crate to one or more of these.

CLI surface

uv-cli defines the entire argument schema using Clap derive macros (crates/uv-cli/src/lib.rs). The top-level Commands enum branches into Auth, Project (the project workflow commands init, add, remove, lock, sync, run, version, tree, export, audit, format), Tool (uvx), Python, Pip (pip-compatible interface), Workspace, Cache, Self, and the standalone BuildBackend and Publish commands.

The actual command implementations live in crates/uv/src/commands/ — one module per command family (pip/, project/, python/, tool/, auth/, workspace/). Settings parsing is centralized in crates/uv/src/settings.rs, which merges environment variables, uv.toml and pyproject.toml configuration, and CLI flags into per-command settings structs.

Configuration and project model

  • uv-workspace parses pyproject.toml (including uv extensions), resolves workspace membership across multiple pyproject.toml files, and provides a mutable TOML model used by uv add and uv remove.
  • uv-settings defines the on-disk uv.toml schema and hierarchical configuration discovery (user → project → CLI).
  • uv-configuration holds typed enums for resolution and build modes (resolution strategies, link modes, target platforms, keyring providers, trusted hosts).
  • uv-pep440 and uv-pep508 implement the Python packaging specifications: versions, specifiers, requirements, and markers, plus their serialization via rkyv for fast cache reads.
  • uv-pypi-types defines wire types shared with PyPI Simple API responses and core metadata.

Dependency resolution

uv-resolver is the heart of the project. It uses PubGrub (vendored as astral-pubgrub) to solve a SAT-style problem over Python distributions, with extensions for:

  • Universal resolution via "forks" — the resolver explores marker-disjoint subsets of the version space in parallel to produce a single lockfile that works on every supported platform and Python version (crates/uv-resolver/src/resolver/environment.rs, crates/uv-resolver/src/universal_marker.rs).
  • Conflict markers and dependency groups (crates/uv-resolver/src/lock/mod.rs).
  • Pre-release handling, exclude-newer cutoffs, hash strategy, yank policies.
  • Lockfile reading/writing and Pylock TOML emission (crates/uv-resolver/src/lock/).

Resolution feeds on metadata from uv-distribution and uv-client, with uv-cache backing both.

Installer and environments

After resolution, uv-installer plans which wheels need to be fetched and installed (crates/uv-installer/src/plan.rs), prepares them via parallel downloads (preparer.rs), and installs them into the target virtual environment using uv-install-wheel for wheel layout. It can also compile bytecode in parallel using rayon (crates/uv-installer/src/compile.rs).

Virtual environments themselves are created by uv-virtualenv, a Rust port of python -m venv that does not require Python at creation time.

Python management

uv-python handles everything related to Python interpreters:

  • Discovery (crates/uv-python/src/discovery.rs — 175k characters) over PATH, virtual environments, the Windows registry, the Microsoft Store, and uv's managed install directory.
  • Querying (crates/uv-python/src/interpreter.rs) — runs a Python script that introspects sys, sysconfig, and platform to populate a MarkerEnvironment.
  • Managed installations (crates/uv-python/src/managed.rs, crates/uv-python/src/downloads.rs) — download and unpack python-build-standalone builds. The full download manifest is shipped in crates/uv-python/download-metadata.json and refreshed by the fetch-download-metadata.py script.

Build system integration

uv ships both halves of PEP 517:

  • uv-build-frontend calls into arbitrary build backends (setuptools, hatch, flit, meson-python, uv_build, …) by spawning Python with the right ephemeral environment. It implements prepare_metadata_for_build_*, build_wheel, and build_sdist PEP 517 hooks.
  • uv-build-backend is uv's own minimal backend (the uv_build PyPI package). It produces wheels and sdists for pure-Python projects without invoking a separate build tool.

Tools and publish

  • uv-tool implements uv tool install, uv tool run (i.e., uvx), uv tool list, and uv tool upgrade. It maintains a per-tool environment under tool-dir, plus a "receipt" describing what was installed.
  • uv-publish uploads wheels and sdists to PyPI-compatible indexes, including OIDC-based trusted publishing.
  • uv-auth provides the credential cache, keyring abstraction, and trusted-publishing token retrieval used by both the registry client and the publisher.

Platform glue

  • uv-trampoline-builder generates Windows console-script shims using prebuilt no_std binaries from crates/uv-trampoline.
  • uv-windows and uv-unix hold platform-specific helpers.
  • uv-shell detects the active shell for shell completions.
  • uv-fs wraps fs-err with locked-file primitives and path simplification used everywhere.

Command flow

The clearest way to picture uv is to follow a uv add requests invocation through the system.

flowchart TD
    cli["`uv add requests`<br/>parse with clap"] --> settings[Resolve settings<br/>uv-settings, uv-configuration]
    settings --> workspace[Discover workspace<br/>uv-workspace]
    workspace --> python[Find / install Python<br/>uv-python]
    python --> venv[Create / reuse .venv<br/>uv-virtualenv]
    workspace --> mutate["Edit pyproject.toml<br/>uv-workspace::pyproject_mut"]
    mutate --> resolve[Resolve dependencies<br/>uv-resolver + uv-distribution + uv-client]
    resolve --> cache[(Cache: ~/.cache/uv<br/>uv-cache)]
    resolve --> lock[Write uv.lock<br/>uv-resolver::lock]
    lock --> plan[Plan installs<br/>uv-installer::Planner]
    plan --> prepare[Download / build wheels<br/>uv-installer::Preparer + uv-build-frontend]
    prepare --> install[Link wheels into .venv<br/>uv-installer::Installer + uv-install-wheel]
    install --> done["Print summary &<br/>compile bytecode"]

The same pipeline (settings → workspace → resolver → installer) underlies almost every project command. uv pip install skips the workspace and project lockfile and goes straight from requirements to resolver to installer. uv tool install follows the project flow but installs into a per-tool environment under tool-dir instead of .venv. uv run syncs first and then spawns a child process inside the resulting environment (crates/uv/src/child.rs).

Cross-cutting infrastructure

  • Async runtime — uv uses tokio for HTTP and filesystem I/O. The resolver itself drives pubgrub on an OS thread (thread::scope in crates/uv-resolver/src/resolver/mod.rs) while prefetching candidate metadata over channels. CPU-bound work like wheel installation and bytecode compilation uses rayon.
  • Caching — A single global cache at ~/.cache/uv stores HTTP responses (zstd-compressed rkyv archives), unpacked wheels, built source distributions, and resolver metadata. The layout is owned by uv-cache.
  • Loggingtracing everywhere. RUST_LOG=trace and --verbose switch logging on; an optional tracing-durations-export feature in crates/uv/Cargo.toml produces span timelines for performance analysis.
  • Error handlingthiserror for typed errors, miette for fancy error reports. anyhow is used in the binary crate for top-level orchestration.
  • Snapshot tests — Most integration tests live in crates/uv/tests/it/ and use insta plus the project-defined uv_snapshot! macro to assert on full CLI output.

Where to look next

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – uv wiki | Factory