Python Dependency Management: Is `uv` the Winner?
Python dependency management has been a mess for years. pip, pip-tools, pipenv, poetry, conda—each with trade-offs. Then Astral released uv, and suddenly everything feels fast.
The State of Python Packaging (Before uv)
| Tool | Purpose | Pain Points |
|---|---|---|
| pip | Install packages | No lockfile, slow resolver |
| pip-tools | Lock dependencies | Separate tool, still slow |
| pipenv | All-in-one | Slow, complex, abandoned feel |
| poetry | Modern packaging | Slow resolution, some compatibility issues |
| conda | Scientific computing | Separate ecosystem, mixing issues |
Common refrain: “Why is this so slow?”
Enter uv
Astral (the Ruff creators) built uv—a pip replacement written in Rust:
# Installation
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or with pip (ironic but works)
pip install uv
Speed Comparison
uv is fast. Really fast.
| Operation | pip | uv | Speedup |
|---|---|---|---|
| Install Django | 4.5s | 0.3s | 15x |
| Lock 100 deps | 45s | 1.2s | 37x |
| Create venv | 2.1s | 0.05s | 42x |
| Resolve conflicts | 30s | 0.8s | 37x |
The secret: Rust, parallel downloads, smart caching, and a complete rewrite of the resolver.
Basic Usage
Package Installation
# Drop-in pip replacement
uv pip install django
uv pip install -r requirements.txt
# Or use the simpler syntax
uv add django # Adds to pyproject.toml and installs
uv remove django # Removes cleanly
Virtual Environments
# Create
uv venv
# Create with specific Python
uv venv --python 3.12
# Activate (same as before)
source .venv/bin/activate
Project Management
# Initialize new project
uv init my-project
cd my-project
# Add dependencies
uv add django
uv add pytest --dev # Development dependency
# Lock dependencies
uv lock
# Sync environment with lockfile
uv sync
pyproject.toml Native
uv uses pyproject.toml as the source of truth:
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"django>=5.0",
"djangorestframework>=3.14",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.1",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.0",
]
Lockfiles
uv generates uv.lock for reproducible installs:
# Generate lockfile
uv lock
# Install exactly what's in lockfile
uv sync
The lockfile is cross-platform by default—it works on Linux, macOS, and Windows.
Python Version Management
uv can manage Python itself:
# List available versions
uv python list
# Install a specific version
uv python install 3.12
# Pin version for project
uv python pin 3.12
No more pyenv? Possibly.
Migration from pip/poetry
From pip + requirements.txt
# Initialize uv in existing project
uv init --no-workspace
# Import requirements
uv add -r requirements.txt
# Generate lockfile
uv lock
From poetry
# Convert poetry to uv
uv init
# Poetry dependencies transfer via pyproject.toml
# uv reads the same [project.dependencies]
uv lock
uv sync
CI/CD Integration
GitHub Actions
- name: Install uv
uses: astral-sh/setup-uv@v2
- name: Install dependencies
run: uv sync
- name: Run tests
run: uv run pytest
Docker
FROM python:3.12-slim
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Copy and install
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
COPY . .
CMD ["uv", "run", "python", "main.py"]
The uv run Command
Run without activating venv:
# Run script
uv run python script.py
# Run with inline dependencies
uv run --with requests python -c "import requests; print(requests.__version__)"
# Run pytest
uv run pytest
Trade-offs
What uv Does Well
- Speed (10-100x faster)
- Clean resolution
- Cross-platform lockfiles
- Single tool for everything
- Active development
Current Limitations
- Newer, less battle-tested
- Some edge cases with complex packages
- Plugin ecosystem still growing
- Some private index configurations
Should You Switch?
Switch now if:
- New projects
- Frustrated with slow poetry/pip
- Simple dependency needs
- Want unified tooling
Wait if:
- Complex existing poetry setup working fine
- Private index complexity
- Need maximum stability
- Can’t afford any migration risk
The Ecosystem Unification
uv is part of Astral’s vision:
- Ruff: Fast linter (replaced flake8, isort)
- uv: Fast package manager (replacing pip, poetry)
- Astral runtime?: Possibly coming
One company addressing Python’s tooling fragmentation with Rust-powered tools.
Final Thoughts
uv feels like the future. It’s fast, well-designed, and actively developed.
Try it on a new project. Feel the speed. Then decide if it’s time to migrate your existing projects.
Python packaging might finally be solved.
Speed is the killer feature nobody knew they needed.