uv: The Python Package Manager That's 100x Faster Than pip
A practical guide to uv—the blazing-fast Python package manager that replaces pip, virtualenv, and pyenv in one tool.
Python’s packaging ecosystem has always been fragmented. You need pip for packages, virtualenv for environments, pyenv for Python versions, and pip-tools for lockfiles. It’s a lot.
uv changes that. It’s a single tool that handles all of it—and it’s 10-100x faster than pip.
Built in Rust by the creators of Ruff, uv is quickly becoming the default choice for Python developers who are tired of slow installs and tool sprawl.
What is uv?
uv is an all-in-one Python package and project manager. It replaces:
- pip — Package installation
- virtualenv/venv — Environment management
- pyenv — Python version management
- pip-tools — Dependency locking
- pipx — Running CLI tools
One tool. Blazing fast. No more juggling multiple commands.
Installation
macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Via Homebrew
brew install uv
Verify installation:
uv --version
Quick Start: Replace pip Today
uv is a drop-in replacement for pip. Your existing commands work with minimal changes.
Create a Virtual Environment
# Old way
python -m venv .venv
# uv way (faster)
uv venv
Install Packages
# Old way
pip install requests flask pandas
# uv way (10-100x faster)
uv pip install requests flask pandas
Install from requirements.txt
# Old way
pip install -r requirements.txt
# uv way
uv pip install -r requirements.txt
Freeze Dependencies
# Old way
pip freeze > requirements.txt
# uv way
uv pip freeze > requirements.txt
That’s it. Same commands, dramatically faster execution.
Speed Comparison
Real-world benchmarks on a typical web project:
| Task | pip | uv | Speedup |
|---|---|---|---|
| Install Django | 4.2s | 0.3s | 14x |
| Install data science stack | 45s | 2.1s | 21x |
| Create virtualenv | 2.8s | 0.1s | 28x |
| Cold install (no cache) | 60s | 3.5s | 17x |
The difference is immediately noticeable. What used to take a minute now takes seconds.
Managing Python Versions
uv can install and manage Python versions, replacing pyenv.
Install Python
# Install specific version
uv python install 3.12
# Install multiple versions
uv python install 3.11 3.12 3.13
List Installed Versions
uv python list
Use a Specific Version
# Create venv with specific Python
uv venv --python 3.12
# Pin version for project
uv python pin 3.12
This creates a .python-version file that uv (and other tools) will respect.
Project Management (The Modern Way)
Beyond drop-in pip replacement, uv offers a modern project workflow similar to Poetry or npm.
Initialize a New Project
uv init my-project
cd my-project
This creates:
pyproject.toml— Project configuration.python-version— Pinned Python versionREADME.md— Documentation.venv— Virtual environment
Add Dependencies
# Add a package
uv add requests
# Add with version constraint
uv add "flask>=2.0"
# Add dev dependency
uv add --dev pytest
uv automatically:
- Updates
pyproject.toml - Generates/updates
uv.lock - Installs the package
Remove Dependencies
uv remove requests
Sync Environment
Ensure your environment matches your lockfile exactly:
uv sync
This is idempotent—run it anytime to get a clean, reproducible environment.
Run Commands
# Run a script
uv run python main.py
# Run pytest
uv run pytest
# Run any command in the project environment
uv run flask run
uv run automatically uses the correct virtual environment without manual activation.
Lockfiles and Reproducibility
uv generates a uv.lock file that pins exact versions of all dependencies (including transitive ones).
Generate/Update Lockfile
uv lock
Install from Lockfile
uv sync
Export to requirements.txt
For compatibility with tools that need requirements.txt:
uv export --format requirements-txt > requirements.txt
Running CLI Tools (pipx Replacement)
uv can run Python CLI tools without permanent installation.
Run Once (Ephemeral)
# Run black formatter without installing
uvx black .
# Run ruff linter
uvx ruff check .
# Run any CLI tool
uvx cowsay "Hello, uv!"
uvx creates a temporary environment, runs the tool, and cleans up.
Install Globally
# Install tool globally
uv tool install ruff
# Now available everywhere
ruff --version
Working with Scripts
uv can manage dependencies for single-file scripts using inline metadata.
Add Dependencies to Script
uv add --script example.py requests
This adds a special comment to your script:
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "requests",
# ]
# ///
import requests
print(requests.get("https://example.com").status_code)
Run the Script
uv run example.py
uv automatically creates an isolated environment with the declared dependencies.
Common Workflows
Starting a New Web Project
uv init my-api
cd my-api
uv add fastapi uvicorn
uv add --dev pytest httpx
uv run uvicorn main:app --reload
Setting Up an Existing Project
git clone https://github.com/example/project
cd project
uv sync # Installs all dependencies from lockfile
uv run pytest
CI/CD Pipeline
# GitHub Actions example
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install dependencies
run: uv sync
- name: Run tests
run: uv run pytest
Configuration
uv reads configuration from pyproject.toml:
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"requests>=2.28",
"flask>=2.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"ruff>=0.1",
]
[tool.uv]
dev-dependencies = [
"pytest>=7.0",
]
Migration Guide
From pip + virtualenv
- Install uv
- Replace
pipwithuv pipin your commands - Replace
python -m venvwithuv venv
That’s it. Your workflow stays the same.
From Poetry
- Convert
pyproject.toml(uv uses standard format) - Remove
poetry.lock, generateuv.lockwithuv lock - Replace
poetry addwithuv add - Replace
poetry installwithuv sync - Replace
poetry runwithuv run
From Conda
uv doesn’t manage non-Python dependencies (like CUDA or system libraries). For pure Python projects:
- Export your environment:
conda list --export > conda-deps.txt - Create requirements from Python packages
- Use uv for Python, keep Conda for system dependencies if needed
Tips and Best Practices
Always Use Lockfiles
# Generate lockfile
uv lock
# Commit uv.lock to git
git add uv.lock
Lockfiles ensure everyone gets identical environments.
Use uv run Instead of Activating
Instead of:
source .venv/bin/activate
python main.py
Do:
uv run python main.py
No activation needed. Works in scripts and CI too.
Cache is Your Friend
uv caches everything globally. Second installs are nearly instant. The cache lives at:
- macOS:
~/Library/Caches/uv - Linux:
~/.cache/uv - Windows:
%LOCALAPPDATA%\uv\cache
Pin Your Python Version
uv python pin 3.12
Creates .python-version for consistency across team members.
When NOT to Use uv
uv is great for most Python projects, but consider alternatives if:
- You need non-Python dependencies: Conda still handles C libraries, CUDA, etc. better
- You’re on an unsupported platform: uv supports macOS, Linux, and Windows, but exotic systems may need pip
- Your organization mandates pip: Some enterprises have strict tooling policies
For most developers, uv is ready for production use.
Summary
| Task | Old Way | uv Way |
|---|---|---|
| Create venv | python -m venv .venv | uv venv |
| Install package | pip install flask | uv add flask |
| Run script | source .venv/bin/activate && python main.py | uv run python main.py |
| Install Python | pyenv install 3.12 | uv python install 3.12 |
| Run CLI tool | pipx run black . | uvx black . |
| Lock dependencies | pip-compile | uv lock |
uv consolidates the Python toolchain into one fast, modern tool. Try it on your next project—the speed difference alone is worth the switch.