File: README.md
uv
An extremely fast Python package and project manager, written in Rust.
Highlights
- A single tool to replace
pip,pip-tools,pipx,poetry,pyenv,twine,virtualenv, and
more. - 10-100x faster than
pip. - Provides comprehensive project management, with a
universal lockfile. - Runs scripts, with support for
inline dependency metadata. - Installs and manages Python versions.
- Runs and installs tools published as Python packages.
- Includes a pip-compatible interface for a performance boost with a familiar
CLI. - Supports Cargo-style workspaces for
scalable projects. - Disk-space efficient, with a global cache for
dependency deduplication. - Installable without Rust or Python via
curlorpip. - Supports macOS, Linux, and Windows.
uv is backed by Astral, the creators of
Ruff and ty.
Installation
Install uv with our standalone installers:
# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Or, from PyPI:
# With pip.
pip install uv# Or pipx.
pipx install uvIf installed via the standalone installer, uv can update itself to the latest version:
uv self updateSee the installation documentation for
details and alternative installation methods.
Documentation
uv's documentation is available at docs.astral.sh/uv.
Additionally, the command line reference documentation can be viewed with uv help.
Features
Projects
uv manages project dependencies and environments, with support for lockfiles, workspaces, and more,
similar to rye or poetry:
$ uv init example
Initialized project `example` at `/home/user/example`
$ cd example
$ uv add ruff
Creating virtual environment at: .venv
Resolved 2 packages in 170ms
Built example @ file:///home/user/example
Prepared 2 packages in 627ms
Installed 2 packages in 1ms
+ example==0.1.0 (from file:///home/user/example)
+ ruff==0.5.0
$ uv run ruff check
All checks passed!
$ uv lock
Resolved 2 packages in 0.33ms
$ uv sync
Resolved 2 packages in 0.70ms
Checked 1 package in 0.02msSee the project documentation to get started.
uv also supports building and publishing projects, even if they're not managed with uv. See the
publish guide to learn more.
Scripts
uv manages dependencies and environments for single-file scripts.
Create a new script and add inline metadata declaring its dependencies:
$ echo 'import requests; print(requests.get("https://astral.sh"))' > example.py
$ uv add --script example.py requests
Updated `example.py`Then, run the script in an isolated virtual environment:
$ uv run example.py
Reading inline script metadata from: example.py
Installed 5 packages in 12ms
<Response [200]>See the scripts documentation to get started.
Tools
uv executes and installs command-line tools provided by Python packages, similar to pipx.
Run a tool in an ephemeral environment using uvx (an alias for uv tool run):
$ uvx pycowsay 'hello world!'
Resolved 1 package in 167ms
Installed 1 package in 9ms
+ pycowsay==0.0.0.2
"""
------------
< hello world! >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||Install a tool with uv tool install:
$ uv tool install ruff
Resolved 1 package in 6ms
Installed 1 package in 2ms
+ ruff==0.5.0
Installed 1 executable: ruff
$ ruff --version
ruff 0.5.0See the tools documentation to get started.
Python versions
uv installs Python and allows quickly switching between versions.
Install multiple Python versions:
$ uv python install 3.12 3.13 3.14
Installed 3 versions in 972ms
+ cpython-3.12.12-macos-aarch64-none (python3.12)
+ cpython-3.13.9-macos-aarch64-none (python3.13)
+ cpython-3.14.0-macos-aarch64-none (python3.14)Download Python versions as needed:
$ uv venv --python 3.12.0
Using Python 3.12.0
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
$ uv run --python [email protected] -- python --version
Python 3.8.16 (a9dbdca6fc3286b0addd2240f11d97d8e8de187a, Dec 29 2022, 11:45:30)
[PyPy 7.3.11 with GCC Apple LLVM 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>>Use a specific Python version in the current directory:
$ uv python pin 3.11
Pinned `.python-version` to `3.11`See the Python installation documentation to get
started.
The pip interface
uv provides a drop-in replacement for common pip, pip-tools, and virtualenv commands.
uv extends their interfaces with advanced features, such as dependency version overrides,
platform-independent resolutions, reproducible resolutions, alternative resolution strategies, and
more.
Migrate to uv without changing your existing workflows โ and experience a 10-100x speedup โ with theuv pip interface.
Compile requirements into a platform-independent requirements file:
$ uv pip compile requirements.in \
--universal \
--output-file requirements.txt
Resolved 43 packages in 12msCreate a virtual environment:
$ uv venv
Using Python 3.12.3
Creating virtual environment at: .venv
Activate with: source .venv/bin/activateInstall the locked requirements:
$ uv pip sync requirements.txt
Resolved 43 packages in 11ms
Installed 43 packages in 208ms
+ babel==2.15.0
+ black==24.4.2
+ certifi==2024.7.4
...See the pip interface documentation to get started.
Contributing
We are passionate about supporting contributors of all levels of experience and would love to see
you get involved in the project. See the
contributing guide to get
started.
FAQ
How do you pronounce uv?
It's pronounced as "you - vee" (/juห viห/)
How should I stylize uv?
Just "uv", please. See the style guide for details.
What platforms does uv support?
See uv's platform support document.
Is uv ready for production?
Yes, uv is stable and widely used in production. See uv's
versioning policy document for details.
Acknowledgements
uv's dependency resolver uses PubGrub under the hood. We're
grateful to the PubGrub maintainers, especially Jacob Finkelman, for
their support.
uv's Git implementation is based on Cargo.
Some of uv's optimizations are inspired by the great work we've seen in pnpm,
Orogene, and Bun. We've also
learned a lot from Nathaniel J. Smith's Posy and adapted its
trampoline
for Windows support.
License
uv is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in uv
by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any
additional terms or conditions.
File: crates/uv-build/README.md
Build backend for uv
This package is a slimmed down version of uv containing only the build backend. See
https://pypi.org/project/uv/ and https://docs.astral.sh/uv/ for the main project package and
documentation.
File: crates/uv-client/README.md
uv-client
This crate is an internal component of uv. The Rust API exposed here
is unstable and will have frequent breaking changes.
This version (0.0.72) is a component of uv 0.12.5. The source
can be found here.
See uv's
crate versioning policy
for details on versioning.
File: crates/uv-globfilter/README.md
globfilter
Portable directory walking with includes and excludes.
Motivating example: You want to allow the user to select paths within a project.
include = ["src", "License.txt", "resources/icons/*.svg"]
exclude = ["target", "/dist", ".cache", "*.tmp"]When traversing the directory, you can useGlobDirFilter::from_globs(...)?.match_directory(&relative) skip directories that never match inWalkDirs filter_entry.
Syntax
This crate supports the cross-language, restricted glob syntax from
PEP 639:
- Alphanumeric characters, underscores (
_), hyphens (-) and dots (.) are matched verbatim. - The special glob characters are:
*: Matches any number of characters except path separators?: Matches a single character except the path separator**: Matches any number of characters including path separators[], containing only the verbatim matched characters: Matches a single of the characters
contained. Within[...], the hyphen indicates a locale-agnostic range (e.g.,a-z, order
based on Unicode code points). Hyphens at the start or end are matched literally.
- The path separator is the forward slash character (
/). Patterns are relative to the given
directory, a leading slash character for absolute paths is not supported. - Parent directory indicators (
..) are not allowed.
These rules mean that matching the backslash (\) is forbidden, which avoid collisions with the
windows path separator.
File: crates/uv-python/python/packaging/README.md
`pypa/packaging`
This directory contains vendored pypa/packaging modules as of
cc938f984bbbe43c5734b9656c9837ab3a28191f.
The files are licensed under BSD-2-Clause OR Apache-2.0.
Patches
The following patches have been applied:
File: crates/uv-trampoline/README.md
Windows trampolines
This is a fork of
posy trampolines.
Building
The trampolines checked into the repo use a reproducible dockerfile for auditing.
scripts/build-trampolines.shThe other build options exist for local development.
Cross-compiling from Linux
Install cargo xwin. Use your package manager to install
LLD and add the rustup targets:
sudo apt install llvm clang lld
cargo install --locked [email protected]
rustup toolchain install nightly-2025-11-02
rustup component add rust-src --toolchain nightly-2025-11-02-x86_64-unknown-linux-gnu
rustup target add --toolchain nightly-2025-11-02 i686-pc-windows-msvc
rustup target add --toolchain nightly-2025-11-02 x86_64-pc-windows-msvc
rustup target add --toolchain nightly-2025-11-02 aarch64-pc-windows-msvcThen, build the trampolines for all supported architectures:
cargo +nightly-2025-11-02 xwin build --xwin-arch x86 --release --target i686-pc-windows-msvc
cargo +nightly-2025-11-02 xwin build --release --target x86_64-pc-windows-msvc
cargo +nightly-2025-11-02 xwin build --release --target aarch64-pc-windows-msvcCross-compiling from macOS
Install cargo xwin. Use your package manager to install
LLVM and add the rustup targets:
brew install llvm
cargo install --locked [email protected]
rustup toolchain install nightly-2025-11-02
rustup component add rust-src --toolchain nightly-2025-11-02-aarch64-apple-darwin
rustup target add --toolchain nightly-2025-11-02 i686-pc-windows-msvc
rustup target add --toolchain nightly-2025-11-02 x86_64-pc-windows-msvc
rustup target add --toolchain nightly-2025-11-02 aarch64-pc-windows-msvcThen, build the trampolines for all supported architectures:
cargo +nightly-2025-11-02 xwin build --xwin-arch x86 --release --target i686-pc-windows-msvc
cargo +nightly-2025-11-02 xwin build --release --target x86_64-pc-windows-msvc
cargo +nightly-2025-11-02 xwin build --release --target aarch64-pc-windows-msvcUpdating the prebuilt executables
After building the trampolines for all supported architectures:
cp target/aarch64-pc-windows-msvc/release/uv-trampoline-console.exe ../uv-trampoline-builder/trampolines/uv-trampoline-aarch64-console.exe
cp target/aarch64-pc-windows-msvc/release/uv-trampoline-gui.exe ../uv-trampoline-builder/trampolines/uv-trampoline-aarch64-gui.exe
cp target/x86_64-pc-windows-msvc/release/uv-trampoline-console.exe ../uv-trampoline-builder/trampolines/uv-trampoline-x86_64-console.exe
cp target/x86_64-pc-windows-msvc/release/uv-trampoline-gui.exe ../uv-trampoline-builder/trampolines/uv-trampoline-x86_64-gui.exe
cp target/i686-pc-windows-msvc/release/uv-trampoline-console.exe ../uv-trampoline-builder/trampolines/uv-trampoline-i686-console.exe
cp target/i686-pc-windows-msvc/release/uv-trampoline-gui.exe ../uv-trampoline-builder/trampolines/uv-trampoline-i686-gui.exeTesting the trampolines
To perform a basic smoke test of the trampolines, run the following commands on a Windows machine,
from the root of the repository:
cargo clean
cargo run venv
cargo run pip install black
.venv\Scripts\black --versionBackground
What is this?
Sometimes you want to run a tool on Windows that's written in Python, like black or mypy orjupyter or whatever. But, Windows does not know how to run Python files! It knows how to run.exe files. So we need to somehow convert our Python file a .exe file.
That's what this does: it's a generic "trampoline" that lets us generate custom .exes for
arbitrary Python scripts, and when invoked it bounces to invoking python instead.
How do you use it?
Basically, this looks up python.exe (for console programs) and invokespython.exe path\to\the\.
It uses PE resources to store/load the information required to do this:
| Resource name | Contains |
|---|---|
RESOURCE_TRAMPOLINE_KIND |
1 (script) or 2 (Python launcher) |
RESOURCE_PYTHON_PATH |
Path to python.exe |
RESOURCE_SCRIPT_DATA |
Zip file, containing a Python script called __main__.py |
This works because when you run python on the .exe, the zipimport mechanism will see the
embedded .zip file, and automagically look inside to find and execute __main__.py. Easy-peasy.
Why does this exist?
I probably could have used Vinay's C++ implementation from distlib, but what's the fun in that? In
particular, optimizing for binary size was entertaining (these are ~7x smaller than the distlib,
which doesn't matter much, but does a little bit, considering that it gets added to every Python
script). There are also some minor advantages, like I think the Rust code is easier to understand
(multiple files!) and it's convenient to be able to straightforwardly code the Python-finding logic
we want. But mostly it was just an interesting challenge.
This does owe a lot to the distlib implementation though. The overall logic is copied
more-or-less directly.
Anything I should know for hacking on this?
In order to minimize binary size, this uses, panic="abort", and carefully avoids usingcore::fmt. This removes a bunch of runtime overhead: by default, Rust "hello world" on Windows is
~150 KB! So these binaries are ~10x smaller.
Of course the tradeoff is that this is an awkward super-limited environment. No C runtime and
limited platform APIs... you don't even panicking support by default. To work around this:
We use
windowsto access Win32 APIs directly. Who needs a C runtime? Though uh, this does mean
that literally all of our code isunsafe. Sorry!diagnostics.rsusesufmtand some cute Windows tricks to get a convenient version ofeprintln!that works withoutcore::fmt, and automatically prints to either the console if
available or pops up a message box if not.All the meat is in
bounce.rs.
Miscellaneous tips:
cargo-bloatis a useful tool for checking what code is ending up in the final binary and how
much space it's taking. (It makes it very obvious whether you've pulled incore::fmt!)Lots of Rust built-in panicking checks will pull in
core::fmt, e.g., if you ever use.unwrap()
then suddenly our binaries double in size, because theif foo.is_none() { panic!(...) }that's
hidden inside.unwrap()will invokecore::fmt, even if the unwrap will actually never fail..unwrap_unchecked()avoids this. Similar forslice[idx]vsslice.get_unchecked(idx).
How do you build this stupid thing?
Building this can be frustrating, because the low-level compiler/runtime machinery have a bunch of
implicit assumptions about the environment they'll run in, and the facilities it provides for things
like memcpy, unwinding, etc. So we need to replace the bits that we actually need, and which bits
we need can change depending on stuff like optimization options. For example: we usepanic="abort", so we don't actually need unwinding support, but at lower optimization levels the
compiler might not realize that, and still emit references to the unwinding
helper__CxxFrameHandler3. And then the linker blows up because that symbol doesn't exist.
cargo build --release --target i686-pc-windows-msvc
cargo build --release --target x86_64-pc-windows-msvc
cargo build --release --target aarch64-pc-windows-msvcFile: crates/uv-virtualenv/README.md
uv-virtualenv
uv-virtualenv is a rust library to create Python virtual environments. It also has a CLI.
Syncing with upstream virtualenv activation scripts
This crate tries to stay in sync with pypa/virtualenv project's activation scripts. However, there
are some deviations that are specific to this crate's implementation.
License disclaimers added
This crate includes license information at the top of each activation script. This is done in
accordance with the pypa/virtualenv project's MIT License. Do not remove the declarative license
comments from this crate's activation scripts.
Placeholder names are slightly different
Note, these activation scripts are actually templates that are populated with certain values when a
virtual environment is created.
In upstream, the placeholder names are found invirtualenv.activation.ViaTemplateActivator.replacements().
In this crate, the placeholder names are found inuv_virtualenv::virtualenv::create()
It is important that the placeholder names (as used in the activation scripts) conform to the
placeholders names used in this crate's source.
Relocatable virtual environments
This crate uses some additional tweaks in the activation scripts to ensure the virtual environment
is relocatable. Thus, the patch in astral-sh/uv#5640 shall be retained.
TCL/TK library locations
The patches in upstream virtualenv (pypa/virtualenv#2928 and pypa/virtualenv#2940) implement
dynamically locating the TCL/TK libraries of a base Python distribution (see upstream
approach).
This upstream implementation is considered an undesirable complexity in this project. As such, the
upstream TCL/TK related patches shall be omitted when syncing activation scripts with upstream
sources.
File: crates/README.md
Crates
[uv-bench](./uv-bench)
Functionality for benchmarking uv.
[uv-cache-key](./uv-cache-key)
Generic functionality for caching paths, URLs, and other resources across platforms.
[uv-distribution-filename](./uv-distribution-filename)
Parse built distribution (wheel) and source distribution (sdist) filenames to extract structured
metadata.
[uv-distribution-types](./uv-distribution-types)
Abstractions for representing built distributions (wheels) and source distributions (sdists), and
the sources from which they can be downloaded.
[uv-install-wheel-rs](./uv-install-wheel)
Install built distributions (wheels) into a virtual environment.
[uv-once-map](./uv-once-map)
A waitmap-like concurrent hash map for executing tasks
exactly once.
[uv-pep440-rs](./uv-pep440)
Utilities for interacting with Python version numbers and specifiers.
[uv-pep508-rs](./uv-pep508)
Utilities for parsing and evaluating
dependency specifiers,
previously known as PEP 508.
[uv-platform-tags](./uv-platform-tags)
Functionality for parsing and inferring Python platform tags as per
PEP 425.
[uv-cli](./uv-cli)
Command-line interface for the uv package manager.
[uv-build-frontend](./uv-build-frontend)
A PEP 517-compatible build frontend for uv.
[uv-cache](./uv-cache)
Functionality for caching Python packages and associated metadata.
[uv-client](./uv-client)
Client for interacting with PyPI-compatible HTTP APIs.
[uv-dev](./uv-dev)
Development utilities for uv.
[uv-dispatch](./uv-dispatch)
A centralized struct for resolving and building source distributions in isolated environments.
Implements the traits defined in uv-types.
[uv-distribution](./uv-distribution)
Client for interacting with built distributions (wheels) and source distributions (sdists). Capable
of fetching metadata, distribution contents, etc.
[uv-extract](./uv-extract)
Utilities for extracting files from archives.
[uv-fs](./uv-fs)
Utilities for interacting with the filesystem.
[uv-git](./uv-git)
Functionality for interacting with Git repositories.
[uv-installer](./uv-installer)
Functionality for installing Python packages into a virtual environment.
[uv-python](./uv-python)
Functionality for detecting and leveraging the current Python interpreter.
[uv-netrc](./uv-netrc)
A vendored netrc parser for uv.
[uv-normalize](./uv-normalize)
Normalize package and extra names as per Python specifications.
[uv-requirements](./uv-requirements)
Utilities for reading package requirements from pyproject.toml and requirements.txt files.
[uv-resolver](./uv-resolver)
Functionality for resolving Python packages and their dependencies.
[uv-shell](./uv-shell)
Utilities for detecting and manipulating shell environments.
[uv-types](./uv-types)
Shared traits for uv, to avoid circular dependencies.
[uv-pypi-types](./uv-pypi-types)
General-purpose type definitions for types used in PyPI-compatible APIs.
[uv-virtualenv](./uv-virtualenv)
A venv replacement to create virtual environments in Rust.
[uv-warnings](./uv-warnings)
User-facing warnings for uv.
[uv-workspace](./uv-workspace)
Workspace abstractions for uv.
[uv-requirements-txt](./uv-requirements-txt)
Functionality for parsing requirements.txt files.