title: uv: Python packaging in Rust
url: https://astral.sh/blog/uv
hash_url: 359df603db
archive_date: 2024-02-17
og_image: https://astral.sh/static/OpenGraph/Astral.jpg
description: uv is an extremely fast Python package installer and resolver, designed as a drop-in alternative to pip and pip-tools.
favicon: https://astral.sh/static/favicon-32x32.png
language: en_US
TL;DR: uv is an extremely fast Python package
installer and resolver, written in Rust, and designed as a drop-in replacement for pip
and
pip-tools
workflows.
uv represents a milestone in our pursuit of a "Cargo for Python": a comprehensive Python project and package manager that's fast, reliable, and easy to use.
As part of this release, we're also taking stewardship of Rye, an experimental Python packaging tool from Armin Ronacher. We'll maintain Rye as we expand uv into a unified successor project, to fulfill our shared vision for Python packaging.
At Astral, we build high-performance developer tools for the Python ecosystem. We're best known for Ruff, an extremely fast Python linter and formatter.
Today, we're releasing the next tool in the Astral toolchain: uv, an extremely fast Python package resolver and installer, written in Rust.
Resolving (left) and installing (right) the Trio dependencies with a warm cache, to simulate recreating a virtual environment or adding a dependency to an existing project (source).
Resolving (top) and installing (bottom) the Trio dependencies with a warm cache, to simulate recreating a virtual environment or adding a dependency to an existing project (source).
uv is designed as a drop-in replacement for pip
and pip-tools
,
and is ready for production use today in projects built around those workflows.
Like Ruff, uv's implementation was grounded in our core product principles:
pip
and pip-tools
without caching, and 80-115x faster
when running with a warm cache (e.g., recreating a virtual environment or updating a dependency).
uv uses a global module cache to avoid re-downloading and re-building dependencies, and
leverages Copy-on-Write and hardlinks on supported filesystems to minimize disk space usage.pip
and pip-tools
APIs behind
our uv pip
interface, making it usable by existing projects with zero configuration.
Similarly, uv can be used as "just" a resolver (uv pip compile
to lock your
dependencies), "just" a virtual environment creator (uv venv
), "just" a package
installer (uv pip sync
), and so on. It's both unified and modular.pip
, pip-tools
, and virtualenv
. uv has no direct Python dependency, so you
can install it separately from Python itself, avoiding the need to manage pip
installations
across multiple Python versions (e.g., pip
vs. pip3
vs. pip3.7
).While uv will evolve into a complete Python project and package manager (a "Cargo for Python"),
the narrower pip-tools
scope allows us to solve the low-level problems involved in building such
a tool (like package installation) while shipping something immediately useful with minimal barrier
to adoption.
You can install uv today via our standalone installers, or from PyPI.
uv supports everything you'd expect from a modern Python packaging tool: editable installs, Git dependencies, URL dependencies, local dependencies, constraint files, source distributions, custom indexes, and more, all designed around drop-in compatibility with your existing tools.
uv supports Linux, Windows, and macOS, and has been tested at-scale against the public PyPI index.
This initial release centers on what we refer to as uv's pip
API. It'll be familiar to those
that have used pip
and pip-tools
in the past:
pip install
, run uv pip install
to install Python dependencies from the command
line, a requirements file, or a pyproject.toml
.pip-compile
, run uv pip compile
to generate a locked requirements.txt
.pip-sync
, run uv pip sync
to sync a virtual environment with a locked requirements.txt
.By scoping these "lower-level" commands under uv pip
, we retain space in the CLI for the more
"opinionated" project management API we intend to ship in the future, which will look more like
Rye, or Cargo, or
Poetry. (Imagine uv run
, uv build
, and so on.)
uv can also be used as a virtual environment manager via uv venv
. It's about 80x
faster than python -m venv
and 7x faster than virtualenv
, with no dependency on Python.
uv's virtual environments are standards-compliant and work interchangeably with other tools — there's no lock-in or customization.
Building our own package management stack from scratch also opened up room for new capabilities. For example:
--resolution=lowest
, library authors can test their packages against the lowest-compatible version of their dependencies. (This is similar to Go's
Minimal version selection.)pip
and pip-tools
always resolve against the currently-installed Python version (generating, e.g., a
Python 3.12-compatible resolution when running under Python 3.12), uv accepts
a --python-version
parameter, enabling you to generate, e.g., Python 3.7-compatible resolutions
even when running under newer versions.-o overrides.txt
), which allow the user to guide the resolver by
overriding the declared dependencies of a package. Overrides give the user an escape hatch for
working around erroneous upper bounds and other incorrectly-declared dependencies.In its current form, uv won't be the right fit for all projects. pip
is a mature and stable
tool, with extensive support for an extremely wide range of use cases and a focus on compatibility.
While uv supports a large fraction of the pip
interface, it lacks support for some of its
legacy features, like .egg
distributions.
Similarly, uv does not yet generate a platform-agnostic lockfile. This matches pip-tools
, but
differs from Poetry and PDM, making uv a better fit for projects built around the pip
and
pip-tools
workflows.
For those deep in the packaging ecosystem, uv also includes standards-compliant Rust implementations of PEP 440 (version identifiers), PEP 508 (dependency specifiers), PEP 517 (a build-system independent build frontend), PEP 405 (virtual environments), and more.
uv represents an intermediary milestone in our pursuit of a "Cargo for Python": a unified Python package and project manager that is extremely fast, reliable, and easy to use.
Think: a single binary that bootstraps your Python installation and gives you everything you need to
be productive with Python, bundling not only pip
, pip-tools
, and virtualenv
, but also pipx
,
tox
, poetry
, pyenv
, ruff
, and more.
Python tooling can be a low-confidence experience: it's a significant amount of work to stand up a new or existing project, and commands fail in confusing ways. In contrast, when working in the Rust ecosystem, you trust the tools to succeed. The Astral toolchain is about bringing Python from a low-confidence to a high-confidence experience.
This vision for Python packaging is not far off from that put forward by Rye, an experimental project and package management tool from Armin Ronacher.
In talking with Armin, it was clear that our visions were closely aligned, but that fulfilling them would require a significant investment in foundational tooling. For example: building such a tool requires an extremely fast, end-to-end integrated, cross-platform resolver and installer. In uv, we've built that foundational tooling.
We saw this as a rare opportunity to team up, and to avoid fragmenting the Python ecosystem. As such, in collaboration with Armin, we're excited to be taking over Rye. Our goal is to evolve uv into a production-ready "Cargo for Python", and to provide a smooth migration path from Rye to uv when the time is right.
Until then, we'll be maintaining Rye, migrating it to use uv under-the-hood, and, more generally, treating it as an experimental testbed for the end-user experience we're building towards.
While merging projects comes with its own challenges, we're committed to building a single, unified tool under the Astral banner, and to supporting existing Rye users as we evolve uv into a suitable and comprehensive successor project.
Following this release, our first priority is to support users as they consider uv, with a focus on improving compatibility, performance, and stability across platforms.
From there, we'll look towards expanding uv into a complete Python project and package manager: a single binary that gives you everything you need to be productive with Python.
We have an ambitious roadmap for uv. But even in its current form, I think it will feel like a very different experience for Python. I hope you'll give it a try.
Finally, we'd like to thank all those that contributed directly or indirectly to the development of uv. Foremost among them are Jacob Finkelman and Matthieu Pizenberg, the maintainers of pubgrub-rs. uv uses PubGrub as its underlying version solver, and we're grateful to Jacob and Matthieu for the work they put into PubGrub in the past, and for the way they've engaged with us as collaborators throughout the project.
We'd also like to thank those projects in the packaging space that've inspired us, especially Cargo, along with Bun, Orogene, and pnpm from the JavaScript ecosystem, and Posy, Monotrail, and Rye from the Python ecosystem. In particular, thanks to Armin Ronacher for collaborating with us on this effort.
Finally, we'd like to thank the maintainers of pip and the members of the PyPA more broadly for all the work they do to make Python packaging possible.