uv — Python package manager
uv is the most recent entrant among Python package and project managers. This article covers uv's origins, role, and relationship to existing tools — based on facts.
Table of contents
uv is the most recent entrant among Python package and project managers. This article covers uv's origins, role, and relationship to existing tools — based on facts.
1. About uv
An open-source tool developed by Astral. Written in Rust. A sister project to Ruff, the Python linter from the same company. The first public release (0.1.0) shipped in February 2024, and project-manager features (uv add, uv sync, uv run) were formally introduced in 0.4 the same year. Dual-licensed MIT / Apache 2.0.
The official tagline — "An extremely fast Python package and project manager, written in Rust." It aims to be a drop-in replacement for pip / pip-tools / virtualenv while folding in Poetry / PDM-style project workflows under one tool.
2. Two modes
uv's modes split roughly into two:
- pip-compatible mode (
uv pip ...) — Run the existingpip install,pip-compile, andpython -m venvflows through the same interface, only faster. CI that assumes only pip can almost swap straight in. - Project mode (
uv add,uv sync,uv run) — Use the[project]metadata (PEP 621) inpyproject.tomland auv.locklockfile as the SSOT for dependency management.
3. Python interpreter management
uv manages the Python interpreter itself. Commands like uv python install 3.12 fetch interpreters separate from the system's, and each project pins a version via .python-version. This area overlaps with what pyenv used to do.
The virtual environment lives at .venv/ inside the project by default. uv run <cmd> runs the command with that virtual environment activated.
4. Other paths
| Tool | First release | Place |
|---|---|---|
| pip | 2008 | Python's standard dependency installer. Maintained by PyPA. |
| virtualenv | 2007 | Ian Bicking. Creates isolated environments. The standard venv module (2012, Python 3.3) absorbed parts of it later. |
| pip-tools | 2012 | pip-compile to produce a lockfile (requirements.txt with pinned versions). |
| Poetry | 2018 | Sébastien Eustace. pyproject.toml + poetry.lock workflow. |
| PDM | 2021 | Included PEP 582 experiments. Faithful to pyproject.toml standards. |
| Hatch | 2022 (rewrite) | Recommended by PyPA. Build, environments, and publishing. |
| uv | 2024 | Astral. Rust. Bundles features of the above tools and emphasizes speed. |
The right choice depends on context. If a Poetry-based codebase already runs well, the case to switch is weak. For new projects or where CI time is the bottleneck, uv shows up often.
5. Common shapes
# Install
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
# macOS · Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Start a project
uv init my-app
cd my-app
uv add fastapi "uvicorn[standard]"
uv add --dev pytest ruff
# Run
uv run python -m uvicorn app:app --reload
uv run pytest
# Sync (reproduce exactly from the lockfile)
uv sync # include dev dependencies
uv sync --frozen --no-dev # recommended for CI · Docker
A pyproject.toml example:
[project]
name = "my-app"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["fastapi>=0.115", "uvicorn[standard]>=0.30"]
[dependency-groups]
dev = ["pytest>=8", "ruff>=0.6"]
6. Docker multi-stage
FROM python:3.12-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "-m", "uvicorn", "app:app", "--host", "0.0.0.0"]
7. Common pitfalls
Active development phase — behavior can shift between minor versions. Pinning the uv version on both CI and local helps reproducibility.
uv.lock is a universal lockfile — covers multiple platforms and Python versions in one file. It is not compatible with Poetry's lockfile format. Re-resolve with uv add when migrating.
uv pip install -r requirements.txt works, but the result doesn't automatically reflect into uv.lock. Mixing the two flows in one project breaks the SSOT.
Some packages have no wheel for certain Python versions and need a source build. The build backends uv invokes are still setuptools / maturin and friends, so the same kind of build tools and headers are required.
Closing thoughts
uv collapses pip-compatible mode, project manager, and interpreter management into one fast tool. The Rust speed shows up most on CI. It takes over the seats Poetry, pip-tools, and pyenv used to share, in a single command surface. That said, pinning versions is the safe move during this active development phase.
Next
- env-and-secrets
- version-managers
References include the official uv docs, uv llms.txt, uv GitHub, Astral's uv announcement post, PEP 621, PyPA Packaging User Guide, Poetry docs, and Ruff docs.
More in tools
All in this category →Related posts
A history of Python dependency tools
Python's packaging and dependency management has seen many tools rise and fall over time. This article walks through them in chronological order and notes what each tool solved, and where it fell short — based on facts.
Python backend folder philosophy
In Python web backends, frameworks rarely enforce a folder layout, so it falls to team agreement. A well-organized layout shortens onboarding for new members; without it, the same patterns get scattered everywhere.
Python and async (asyncio)
Python is a dynamic scripting language first released in 1991. This post covers Python's flow, the GIL, and how asyncio came about. We also touch on the difference between concurrency and parallelism, where ASGI and Fas…
pnpm
pnpm is one of the package managers in the Node.js ecosystem. This article covers pnpm's origins, how it works, and how it differs from other managers — based on facts.