uv: The Python Package Manager That Replaces pip, pip-tools, and venv (2026 Guide)
If you've spent any time in a Python project this year, you've probably seen uv show up in a README or CI file. It's a Rust-written package manager and virtualenv tool from Astral (the same team behind ruff) β and it's 10-100x faster than the classic pip / pip-tools / venv combo.
This guide covers: what uv actually replaces, the five commands that cover 95% of what you do daily, and the two cases where you should stick with the classic tools.
What uv replaces
| Classic tool | uv equivalent | Speed-up |
|---|---|---|
| python -m venv .venv | uv venv | ~5x |
| pip install pkg | uv pip install pkg | ~10-50x |
| pip install -r requirements.txt | uv pip install -r requirements.txt | 20-100x on cold cache |
| pip-compile (pip-tools) | uv pip compile | ~50x |
| python -m venv + source activate for each project | uv run <cmd> | Skips activation entirely |
The speed difference is real. Installing a moderate Django project (Django + DRF + celery + redis + boto3 + ~40 transitive deps) on a cold cache takes ~45 seconds with pip and ~2 seconds with uv. On a warm cache uv is essentially instant because it uses a global hard-linked cache instead of copying files into each venv.
The five commands you'll actually use
1. Install uv itself
BASH# macOS + Linux β one line, no sudo, no Python needed curl -LsSf https://astral.sh/uv/install.sh | sh # Windows PowerShell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" # Or via brew / apt / your package manager (updated frequently) brew install uv
uv is a single self-contained binary β no Python bootstrap, no dependencies of its own.
2. Create a virtualenv
BASHcd my-project uv venv # creates .venv/ using the current Python uv venv --python 3.13 # or pin a version β uv will download it if missing
Unlike python -m venv, uv can fetch the Python version you asked for. No more "pyenv install then venv then activate" three-step dance.
3. Install packages
BASHuv pip install fastapi httpx # into the current venv uv pip install -r requirements.txt # bulk install uv pip install -e . # editable install of current project
Syntax is intentionally identical to pip β swap pip for uv pip and everything works. Migration cost: five keystrokes.
4. Freeze / compile requirements
BASH# From an installed venv β requirements.txt (like `pip freeze`) uv pip freeze > requirements.txt # From a loose requirements.in β fully pinned requirements.txt (like pip-compile) uv pip compile requirements.in -o requirements.txt
The compile step is deterministic β same input, same output, byte-for-byte. Perfect for reproducible CI.
5. Run a command without activating the venv
BASHuv run pytest # runs pytest from the current venv uv run python manage.py migrate # any command, any script uv run --with ipython python # temporarily add ipython for this session
This is the killer feature. No more source .venv/bin/activate before every command. Great in CI, great in Makefiles, great in shell scripts.
Migrating an existing project (2 minutes)
Assuming you have a requirements.txt:
BASH# 1. Nuke the old venv rm -rf .venv # 2. Create the uv venv uv venv # 3. Install uv pip install -r requirements.txt # 4. Verify uv run python -c "import fastapi; print(fastapi.__version__)"
Four commands, done. Your requirements.txt doesn't need to change. Your pyproject.toml doesn't need to change. Your CI barely needs to change β swap the install step and you're done.
The pyproject.toml native path (uv-first projects)
For projects starting from scratch, use uv's native workflow β no requirements.txt at all:
BASHuv init my-project # generates pyproject.toml + .python-version + .gitignore cd my-project uv add fastapi # adds fastapi to pyproject.toml [dependencies] AND installs uv add --dev pytest # adds to dev-dependencies uv sync # installs exactly what pyproject.toml says (uses uv.lock) uv lock --upgrade # bumps every dependency to its latest compatible version
This is the same shape as cargo for Rust or npm for Node β one config file, one lock file, deterministic installs. If you're starting fresh in 2026, this is the path.
When to still use pip / venv
Two cases:
1. Legacy CI systems that can't install uv. If you're stuck with a Jenkins agent from 2019 with no shell access, the friction of installing uv may outweigh the speed gain. Every modern CI system (GitHub Actions, GitLab CI, CircleCI, BuildKite) has a one-line uv installer.
2. Airgapped environments with a locked-down `pip` mirror. uv defaults to PyPI but supports --index-url β this usually works, but some corporate mirrors have subtle behaviours (auth headers, JSON API vs Simple API) that uv handles differently. Test before you commit.
That's it. For every other case in 2026 β solo dev, team projects, open source, CI, Docker β uv is faster, more reliable, and requires less mental overhead than the classic stack.
The 30-second CI swap
Before (GitHub Actions):
YAML- uses: actions/setup-python@v5 with: python-version: '3.13' - run: pip install -r requirements.txt - run: pytest
After:
YAML- uses: astral-sh/setup-uv@v3 - run: uv sync - run: uv run pytest
CI runs drop from ~2 min to ~15 sec on the install step. If your test matrix runs 5x per PR, that's a real cumulative saving.
uv is the rare tool that's both faster AND simpler than what it replaces. If you write Python for a living in 2026, spend 10 minutes switching one project over. The habit will carry to every new project you touch.
Next step: the Python DevOps track covers uv, ruff, Docker, and the modern Python deployment stack β 104 interactive lessons.