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
- Create an environment:
uv venv
- Select the interpreter at
.venv/bin/python
(Unix) or.venv\Scripts\python.exe
(Windows)
L.6.2.2 PyCharm
- Create an environment:
uv venv
- 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:
- Define direct dependencies in a
requirements.in
file with minimal version constraints - Compile locked requirements with
uv pip compile requirements.in -o requirements.txt
- Install dependencies with
uv pip sync requirements.txt
- 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.