uv is a blisteringly fast Python package installer and resolver, written in Rust, designed as a drop-in replacement for pip and pip-tools. It serves as the backbone for the next-generation Python package manager, Rye, but is a powerful standalone tool. Its primary value proposition is speed, often achieving performance an order of magnitude greater than traditional tools by leveraging a highly parallelized architecture and a global, persistent cache.

Core Installation and Setup

uv can be installed standalone or as part of Rye. The most direct method is via curl:

curl -LsSf https://astral.sh/uv/install.sh | sh

This installs uv into ~/.cargo/bin by default. On Windows, you can use powershell:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Once installed, you can begin using it immediately. Its CLI is designed to be familiar to pip users, significantly lowering the adoption barrier. You can verify the installation and check the version with:

uv --version

Basic Package Management Commands

The core workflow for installing packages mirrors pip almost exactly. To install a single package, such as requests, into your current environment:

uv pip install requests

The pip subcommand is used to indicate that you are performing pip-compatible operations. To install multiple packages and their dependencies:

uv pip install requests httpx beautifulsoup4

The speed difference here is immediately apparent; uv resolves dependencies and downloads wheels in parallel, utilizing a shared global cache. This means if you’ve ever installed requests in any project or environment on your system, subsequent installs are nearly instantaneous as uv will reuse the cached wheel.

Uninstalling a package is equally straightforward:

uv pip uninstall httpx

Dependency Resolution and the Lockfile

A critical feature of uv is its robust and extremely fast dependency resolver. Unlike pip’s resolver, which can be slow and sometimes backtrack endlessly, uv uses a modern, PubGrub-based resolver. This results in faster, more correct resolutions, especially for complex dependency graphs.

To generate a lockfile (uv.lock) from a requirements.in or pyproject.toml file, you use the uv lock command. This is the equivalent of pip-compile from pip-tools.

# If you have a requirements.in file
uv lock -r requirements.in

# Or, to read from a pyproject.toml (like with Rye or a PEP 621 project)
uv lock

The resulting uv.lock file contains all primary and transitive dependencies pinned to exact versions, ensuring reproducible installs across different systems. You can then install from this lockfile:

uv sync

The uv sync command is a best practice. It doesn’t just install packages; it synchronizes your environment to exactly match the lockfile. If a package is present in the environment but not in the lockfile, uv sync will remove it. This guarantees environment parity, a common pitfall where developers use pip install -r requirements.txt but have stray packages causing “but it works on my machine” issues.

Advanced Usage: Creating Virtual Environments

While uv can install packages into any existing environment (by using the --python flag to point to it), it excels at creating and managing its own virtual environments. The uv venv command creates a new virtual environment.

# Create a virtual environment named `.venv`
uv venv

# Create a virtual environment with a specific Python version
uv venv --python 3.11

# Create a virtual environment with a specific name
uv venv my_env

The key advantage here is speed. uv does not simply call the standard library’s venv module; it implements its own virtual environment creation logic, making it significantly faster. After creating an environment, you can activate it as usual or have uv run commands inside it directly using uv run.

# Activate on Unix/macOS
source .venv/bin/activate

# Activate on Windows
.venv\Scripts\activate

# Or, run a command directly inside the environment without activation
uv run python script.py
uv run pytest

Integration with pyproject.toml and Best Practices

uv is built for the modern Python ecosystem and has first-class support for pyproject.toml (PEP 621). The optimal workflow involves using uv alongside a pyproject.toml file that defines your dependencies.

  1. Define your dependencies: List your main dependencies in the project.dependencies section of your pyproject.toml.
    [project]
    name = "my-project"
    version = "0.1.0"
    dependencies = [
        "requests>=2.28.0",
        "httpx",
    ]
    
  2. Generate the lockfile: Run uv lock to resolve all dependencies and create a uv.lock file.
  3. Synchronize the environment: Run uv sync to create a virtual environment (if it doesn’t exist) and install all packages from the lockfile into it. This is a single, idempotent command that ensures correctness.

This workflow eliminates the need for separate requirements.txt files and ensures that your environment is always a perfect reflection of your declared dependencies and their resolved, compatible versions. It is the most robust way to avoid version conflicts and deployment surprises.