Appendix L — UV - High-Performance Python Package Management

L.1 Introduction to uv

uv is a modern, high-performance Python package installer and resolver written in Rust. Developed by Astral, it represents a significant evolution in Python tooling, designed to address the performance limitations of traditional Python package management tools while maintaining compatibility with the existing Python packaging ecosystem.

Unlike older tools that are written in Python itself, uv’s implementation in Rust gives it exceptional speed advantages—often 10-100x faster than traditional tools for common operations. This performance boost is particularly noticeable in larger projects with complex dependency graphs.

L.2 Key Features and Benefits

L.2.1 Performance

Performance is uv’s most distinctive feature:

  • Parallel Downloads: Downloads and installs packages in parallel
  • Optimized Dependency Resolution: Efficiently resolves dependencies with a modern algorithm
  • Cached Builds: Maintains a build artifact cache to avoid redundant work
  • Rust Implementation: Low memory usage and high computational efficiency

In practical terms, this means environments that might take minutes to create with traditional tools can be ready in seconds with uv.

L.2.2 Compatibility

Despite its modern architecture, uv maintains compatibility with Python’s ecosystem:

  • Standard Wheel Support: Installs standard Python wheel distributions
  • PEP Compliance: Follows relevant Python Enhancement Proposals for packaging
  • Requirements.txt Support: Works with traditional requirements files
  • pyproject.toml Support: Compatible with modern project configurations

L.2.3 Unified Functionality

uv combines features from several traditional tools:

  • Environment Management: Similar to venv but faster
  • Package Installation: Like pip but with parallel processing
  • Dependency Resolution: Similar to pip-tools but more efficient
  • Lockfile Generation: Creates deterministic environments like pip-compile

L.3 Getting Started with uv

L.3.1 Installation

uv can be installed in several ways:

# Using pipx (recommended for CLI usage)
pipx install uv

# Using pip
pip install uv

# Using curl (Unix systems)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Using PowerShell (Windows)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

L.3.2 Basic Commands

uv has an intuitive command structure that will feel familiar to pip users:

# Create a virtual environment
uv venv

# Install a package
uv pip install requests

# Install from requirements file
uv pip install -r requirements.txt

# Install a package in development mode
uv pip install -e .

L.3.3 Working with Virtual Environments

uv integrates environment management with package installation:

# Create and activate a virtual environment
uv venv
source .venv/bin/activate  # On Unix
# .venv\Scripts\activate  # On Windows

# Or install directly into an environment
uv pip install --venv .venv numpy pandas

L.4 Dependency Management with uv

L.4.1 Compiling Requirements

uv offers an efficient workflow for managing dependencies using a two-file approach similar to pip-tools:

# Create a simple requirements.in file
echo "requests>=2.28.0" > requirements.in

# Compile to a locked requirements.txt
uv pip compile requirements.in -o requirements.txt

# Install the locked dependencies
uv pip sync requirements.txt

The generated requirements.txt will contain exact versions of all dependencies (including transitive ones), ensuring reproducible environments.

L.4.2 Development Dependencies

For more complex projects, you can separate production and development dependencies:

# Create a dev-requirements.in file
echo "-c requirements.txt" > dev-requirements.in
echo "pytest" >> dev-requirements.in
echo "black" >> dev-requirements.in

# Compile development dependencies
uv pip compile dev-requirements.in -o dev-requirements.txt

# Install all dependencies
uv pip sync requirements.txt dev-requirements.txt

The -c requirements.txt constraint ensures compatible versions between production and development dependencies.

L.4.3 Updating Dependencies

When you need to update packages:

# Update all packages to their latest allowed versions
uv pip compile --upgrade requirements.in

# Update a specific package
uv pip compile --upgrade-package requests requirements.in

L.5 Advanced uv Features

L.5.1 Offline Mode

uv supports working in environments without internet access:

# Install using only cached packages
uv pip install --offline numpy

L.5.2 Direct URLs and Git Dependencies

uv can install packages from various sources:

# Install from GitHub
uv pip install git+https://github.com/user/repo.git@branch

# Install from local directory
uv pip install /path/to/local/package

L.5.3 Configuration Options

uv allows configuration through command-line options:

# Set global options
uv pip install --no-binary :all: numpy  # Force source builds
uv pip install --only-binary numpy pandas  # Force binary installations

L.5.4 Performance Optimization

To maximize uv’s performance:

# Use concurrent installations
uv pip install --concurrent-installs numpy pandas matplotlib

# Reuse the build environment
uv pip install --no-build-isolation package-name

L.6 Integration with Workflows

L.6.1 CI/CD Integration

uv is particularly valuable in CI/CD pipelines where speed matters:

# GitHub Actions example
- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: "3.10"

- name: Install uv
  run: pip install uv

- name: Install dependencies
  run: uv pip sync requirements.txt dev-requirements.txt

L.6.2 IDE Integration

While IDEs typically detect standard virtual environments, you can explicitly configure them:

L.6.2.1 VS Code

  1. Create an environment: uv venv
  2. Select the interpreter at .venv/bin/python (Unix) or .venv\Scripts\python.exe (Windows)

L.6.2.2 PyCharm

  1. Create an environment: uv venv
  2. In Settings → Project → Python Interpreter, add the interpreter from the .venv directory

L.7 Comparing uv with Other Tools

L.7.1 uv vs. pip

Feature uv pip
Installation Speed Very fast (parallel) Slower (sequential)
Dependency Resolution Fast, efficient Slower, sometimes problematic
Environment Management Built-in Requires separate tool (venv)
Lock Files Native support Requires pip-tools
Caching Global, efficient More limited
Compatibility High with standard packages Universal

L.7.2 uv vs. pip-tools

Feature uv pip-tools
Speed Very fast Moderate
Implementation Rust Python
Environment Management Integrated Separate (needs venv)
Command Structure uv pip compile/sync pip-compile/pip-sync
Hash Generation Supported Supported

L.7.3 uv vs. Poetry/PDM

Feature uv Poetry/PDM
Focus Performance Project management
Configuration Minimal (uses standard files) More extensive
Learning Curve Gentle (similar to pip) Steeper
Project Structure Flexible More opinionated
Publishing to PyPI Basic support Comprehensive support

L.8 Best Practices with uv

L.8.1 Dependency Management Workflow

A recommended workflow using uv for dependency management:

  1. Define direct dependencies in a requirements.in file with minimal version constraints
  2. Compile locked requirements with uv pip compile requirements.in -o requirements.txt
  3. Install dependencies with uv pip sync requirements.txt
  4. Update dependencies periodically with uv pip compile --upgrade requirements.in

L.8.2 Optimal Project Structure

A simple project structure that works well with uv:

my_project/
├── .venv/                    # Created by uv venv
├── src/                      # Source code
│   └── my_package/
├── tests/                    # Test files
├── requirements.in           # Direct dependencies
├── requirements.txt          # Locked dependencies (generated)
├── dev-requirements.in       # Development dependencies
├── dev-requirements.txt      # Locked dev dependencies (generated)
└── pyproject.toml            # Project configuration

L.8.3 Version Control Considerations

When using version control with uv:

  • Commit both .in and .txt files to ensure reproducible builds
  • Add .venv/ to your .gitignore
  • Consider committing hash-verified requirements for security

L.9 Troubleshooting uv

L.9.1 Common Issues and Solutions

L.9.1.1 Missing Binary Wheels

If you encounter issues with packages requiring compilation:

# Try forcing binary wheels
uv pip install --only-binary :all: package-name

# Or for a specific package
uv pip install --only-binary package-name package-name

L.9.1.2 Dependency Conflicts

For dependency resolution issues:

# Get detailed information about conflicts
uv pip install --verbose package-name

# Try installing with more permissive constraints
uv pip install --no-deps package-name
# Then fix specific dependencies

L.9.1.3 Environment Problems

If environments aren’t working properly:

# Create a fresh environment
rm -rf .venv
uv venv

# Or use a specific Python version
uv venv --python 3.9

L.10 Conclusion

uv represents an exciting advancement in Python tooling, offering significant performance improvements while maintaining compatibility with existing workflows. Its speed benefits are particularly valuable for:

  • CI/CD pipelines where build time matters
  • Large projects with many dependencies
  • Development environments with frequent updates
  • Teams looking to improve developer experience

While newer than some traditional tools, uv’s compatibility with standard Python packaging conventions makes it a relatively low-risk adoption with potentially high rewards in terms of productivity and performance. As it continues to mature, uv is positioned to become an increasingly important part of the Python development ecosystem.

For most projects, uv can be a drop-in replacement for pip and pip-tools, offering an immediate performance boost without requiring significant workflow changes—a rare combination of revolutionary performance with evolutionary adoption requirements.