Python uv Package Manager 2026: The 10x Faster pip Replacement Guide
The Dark Ages of Python Dependency Management
Every Python developer has experienced these pains:
- pip installs at a snail's pace: A Django project
pip installcan take minutes, with dependency resolution stuck at theCollectingstage driving you crazy - poetry configuration is incomprehensible:
pyproject.tomldependency groups, extras, and source configurations are headache-inducing, and lock file conflicts are commonplace - venv manual management is tedious:
python -m venv .venv,source .venv/bin/activate,deactivate... repeating this workflow for every project - Python version switching is chaotic: pyenv, conda, and system Python fighting each other,
which pythonnever pointing where you expect - Dependency locking is unreliable:
requirements.txthas no lock file,pip freeze > requirements.txtincludes transitive dependencies, making environments non-reproducible
In 2024, the Astral team (creators of ruff) released uv -- a Python package manager written in Rust, 10-100x faster than pip. By 2026, uv has become the most watched package management tool in the Python ecosystem, supporting project management, virtual environments, Python version management, Monorepo workspaces, and more.
This article will guide you through mastering uv via 5 practical patterns, starting from core concepts.
Core Concepts Reference
| Concept | Description | Command |
|---|---|---|
| Project Management | Initialize projects, manage dependency declarations | uv init, uv add, uv remove |
| Virtual Environment | Automatically create and manage .venv | uv venv, uv sync |
| Python Version Management | Install and switch Python interpreters | uv python install, uv python pin |
| Dependency Locking | Generate reproducible lock files | uv lock (auto-generates uv.lock) |
| Dependency Resolution | High-performance dependency tree resolution | Built-in Rust resolver, 10-100x speedup |
| Workspace | Monorepo multi-package management | uv workspace |
| Tool Running | Temporarily install and run CLI tools | uv tool run, uvx |
| Script Execution | Inline dependency declarations and run scripts | uv run script.py |
| Cache Management | Global package cache, avoid redundant downloads | uv cache |
| Export Dependencies | Export to requirements.txt format | uv export |
Five Core Challenges
Challenge 1: Dependency Resolution Speed
pip uses a backtracking resolution algorithm; complex dependency graphs can take minutes or fail entirely. uv employs a high-performance resolver based on a SAT solver, typically completing resolution in milliseconds.
Challenge 2: Environment Consistency
requirements.txt lacks complete dependency locking information; installations on different machines may yield different results. uv's uv.lock lock file records the full dependency tree hashes, ensuring exact reproducibility in any environment.
Challenge 3: Python Version Fragmentation
Different projects require different Python versions; the pyenv + venv combination is cumbersome to configure. uv has built-in Python version management -- one command to install and switch, no additional tools needed.
Challenge 4: Monorepo Dependency Sharing
Multiple sub-packages have internal dependency relationships; traditional approaches require manual publishing to private PyPI or using pip install -e. uv workspace natively supports Monorepo with automatic linking between sub-packages.
Challenge 5: CI/CD Cache Efficiency
pip re-downloads dependencies on every CI run; even with caching, cache misses are frequent. uv's global cache + content-addressable mechanism achieves near-100% CI cache hit rates.
Pattern 1: uv Installation and Project Initialization
Installing uv
# 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"
# Install via pip (not recommended, fallback only)
pip install uv
# Using Homebrew
brew install uv
# Verify installation
uv --version
# uv 0.7.12 (2026 latest stable release)
Project Initialization
# Create a new project
uv init my-project
cd my-project
# Project structure
# my-project/
# ├── .python-version # Python version pin
# ├── pyproject.toml # Project config and dependency declarations
# ├── uv.lock # Dependency lock file (auto-generated)
# ├── hello.py # Sample entry file
# └── .venv/ # Virtual environment (auto-created)
Dependency Management
# Add dependencies
uv add fastapi
uv add "sqlalchemy>=2.0"
uv add --dev pytest
uv add --dev ruff
# Add optional dependency group
uv add --optional ml torch
# Remove dependencies
uv remove pytest
# Sync dependencies (install all declared in pyproject.toml)
uv sync
# Sync production dependencies only (exclude dev)
uv sync --no-dev
# Sync specific group
uv sync --group ml
pyproject.toml Structure
[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115.0",
"sqlalchemy>=2.0",
]
[project.optional-dependencies]
ml = [
"torch>=2.5",
"transformers>=4.45",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.0",
"ruff>=0.8",
]
[tool.uv.sources]
my-private-pkg = { git = "https://github.com/myorg/my-private-pkg.git", tag = "v1.0.0" }
Running Projects
# Run a script in the virtual environment
uv run python hello.py
# Run a module
uv run python -m my_project.main
# Run a script with inline dependency declaration
uv run --with requests python fetch_data.py
Pattern 2: Virtual Environment and Python Version Management
Virtual Environment Management
# Create a virtual environment (default .venv directory)
uv venv
# Create with specific Python version
uv venv --python 3.12
# Specify virtual environment path
uv venv /path/to/.venv
# Activate virtual environment
# macOS / Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate
# uv sync automatically creates virtual environment
uv sync
Python Version Management
# List available Python versions
uv python list
# Install specific Python version
uv python install 3.12
uv python install 3.13
# Install specific implementations
uv python install pypy3.10
uv python install graalpy3.11
# Pin project Python version (writes to .python-version)
uv python pin 3.12
# List installed versions
uv python list --only-installed
# Find Python interpreter path
uv python find 3.12
# Temporarily use a specific version
uv run --python 3.13 python --version
.python-version File
3.12
This file is automatically read by uv, ensuring team members use a consistent Python version. Combined with uv sync, new team members can set up a complete environment with a single command after cloning.
Multi-Version Parallel Scenarios
# Project A uses Python 3.12
cd project-a
uv python pin 3.12
uv sync
# Project B uses Python 3.13
cd project-b
uv python pin 3.13
uv sync
# Projects don't interfere; no pyenv switching needed
Pattern 3: Migration from pip/requirements.txt and poetry/pyproject.toml
Migrating from pip + requirements.txt
# Option 1: Initialize in an existing project
cd existing-project
uv init
# uv detects existing requirements.txt and auto-imports
# Option 2: Manually import dependencies
uv add $(cat requirements.txt | grep -v "^#" | grep -v "^$" | tr "\n" " ")
# Option 3: Use uv pip compatibility mode (transition period)
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
# Export back to requirements.txt format
uv export > requirements.txt
uv export --no-dev > requirements-prod.txt
Migrating from poetry
# uv reads poetry's pyproject.toml directly
cd poetry-project
uv init
# uv auto-detects [tool.poetry.dependencies] and migrates
# Manual migration steps
# 1. Backup poetry.lock
cp poetry.lock poetry.lock.bak
# 2. Convert poetry dependency format to PEP 621 format
# Poetry format:
# [tool.poetry.dependencies]
# fastapi = "^0.115.0"
# PEP 621 format:
# [project]
# dependencies = ["fastapi>=0.115.0"]
# 3. Generate uv.lock
uv lock
# 4. Sync dependencies
uv sync
Poetry to uv pyproject.toml Conversion Script
import tomllib
import tomli_w
from pathlib import Path
def migrate_poetry_to_uv(pyproject_path: str = "pyproject.toml"):
""Convert poetry-format pyproject.toml to uv-compatible format""
path = Path(pyproject_path)
data = tomllib.loads(path.read_text(encoding="utf-8"))
poetry_deps = data.get("TOOL", {}).get("poetry", {}).get("dependencies", {})
poetry_dev_deps = (
data.get("TOOL", {})
.get("poetry", {})
.get("group", {})
.get("dev", {})
.get("dependencies", {})
)
def convert_version(version_spec: str) -> str:
if isinstance(version_spec, dict):
return version_spec.get("version", "*")
if version_spec.startswith("^"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{int(parts[0]) + 1}.0.0"
return f">={base},<{upper}"
if version_spec.startswith("~"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{parts[0]}.{int(parts[1]) + 1}.0"
return f">={base},<{upper}"
return version_spec
dependencies = []
for name, version in poetry_deps.items():
if name == "python":
data.setdefault("project", {})["requires-python"] = f">={version}"
continue
dep = convert_version(version)
dependencies.append(f"{name}{dep}" if dep != "*" else name)
data.setdefault("project", {})["dependencies"] = dependencies
dev_dependencies = []
for name, version in poetry_dev_deps.items():
dep = convert_version(version)
dev_dependencies.append(f"{name}{dep}" if dep != "*" else name)
if dev_dependencies:
data.setdefault("TOOL", {}).setdefault("uv", {})[
"dev-dependencies"
] = dev_dependencies
if "poetry" in data.get("TOOL", {}):
del data["TOOL"]["poetry"]
path.write_text(tomli_w.dumps(data), encoding="utf-8")
print(f"Migration complete: {dependencies=}, {dev_dependencies=}")
if __name__ == "__main__":
migrate_poetry_to_uv()
Migrating from pipenv
# Export Pipfile dependencies to requirements.txt
pipenv requirements > requirements.txt
# Initialize with uv and import
uv init
uv add $(cat requirements.txt | tr "\n" " ")
uv sync
Pattern 4: Monorepo and Workspace Management
Workspace Initialization
# Create Monorepo root directory
mkdir my-monorepo && cd my-monorepo
uv init --workspace
# Create sub-packages
uv init --package libs/core
uv init --package libs/api
uv init --package apps/web
# Project structure
# my-monorepo/
# ├── pyproject.toml # Workspace root config
# ├── uv.lock # Global lock file (unified management)
# ├── libs/
# │ ├── core/
# │ │ ├── pyproject.toml
# │ │ └── src/core/
# │ └── api/
# │ ├── pyproject.toml
# │ └── src/api/
# └── apps/
# └── web/
# ├── pyproject.toml
# └── src/web/
Root pyproject.toml Configuration
[tool.uv.workspace]
members = [
"libs/core",
"libs/api",
"apps/web",
]
[tool.uv.sources]
core = { workspace = true }
api = { workspace = true }
Sub-package pyproject.toml
# libs/core/pyproject.toml
[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.9",
]
# libs/api/pyproject.toml
[project]
name = "api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"fastapi>=0.115.0",
]
# apps/web/pyproject.toml
[project]
name = "web"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"api",
"uvicorn>=0.32.0",
]
Workspace Operations
# Sync entire workspace
uv sync
# Sync specific sub-package only
uv sync --package api
# Run command in specific sub-package
uv run --package api python -m api.main
# Add dependency to specific sub-package
uv add --package api httpx
# Build specific sub-package
uv build --package core
# Publish specific sub-package
uv publish --package core
Workspace Dependency Graph Verification
# View dependency tree
uv tree
# Check dependency conflicts
uv lock --check
# Update specific dependency
uv lock --upgrade-package fastapi
Pattern 5: CI/CD Integration and Docker Optimization
GitHub Actions Integration
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --frozen
- name: Run linter
run: uv run ruff check .
- name: Run tests
run: uv run pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
GitLab CI Integration
# .gitlab-ci.yml
stages:
- test
- build
test:
stage: test
image: python:3.12-slim
before_script:
- pip install uv
- uv python install 3.12
- uv sync --frozen
script:
- uv run ruff check .
- uv run pytest --cov=src
cache:
key:
files:
- uv.lock
paths:
- .venv/
- ~/.cache/uv/
build:
stage: build
image: python:3.12-slim
before_script:
- pip install uv
script:
- uv build
artifacts:
paths:
- dist/
Docker Multi-Stage Build Optimization
# Dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv
FROM python:3.12-slim AS deps
COPY --from=uv /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-install-project --no-dev
FROM python:3.12-slim AS runtime
WORKDIR /app
COPY --from=deps /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
ENV VIRTUAL_ENV="/app/.venv"
CMD ["python", "-m", "my_project.main"]
Docker Compose Development Environment
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- .:/app
- uv-cache:/root/.cache/uv
environment:
- PYTHONUNBUFFERED=1
command: uv run uvicorn my_project.main:app --host 0.0.0.0 --reload
volumes:
uv-cache:
CI Cache Optimization Tips
# Use --frozen to ensure lock file is not modified (required in CI)
uv sync --frozen
# Use --no-dev to reduce install size
uv sync --frozen --no-dev
# Offline install (when dependencies are cached)
uv sync --frozen --offline
Common Pitfalls Guide
Pitfall 1: Mixing pip and uv
❌ Using pip install in a uv-managed project, bypassing uv's dependency management
✅ Always use uv add to add dependencies and uv sync to sync environments. For temporary installs, use uv pip install (compatibility mode)
Pitfall 2: Ignoring uv.lock in Version Control
❌ Adding uv.lock to .gitignore, causing inconsistent dependency versions across team members
✅ Commit uv.lock to version control, ensuring all environments use the same dependency versions. Use --frozen in CI to prevent accidental updates
Pitfall 3: Forgetting to Pin Python Version
❌ Not setting .python-version, causing compatibility issues when developers use different Python versions
✅ Use uv python pin 3.12 to pin the version, and commit .python-version to the repository
Pitfall 4: Global Install Pollution
❌ Installing numerous global tools with uv tool install, making version conflicts hard to troubleshoot
✅ Use uv run --with for project-level temporary installs; only install frequently-used global tools (like ruff, black)
Pitfall 5: Not Leveraging Docker Cache Layers
❌ COPY all source code before uv sync, re-installing dependencies on every code change
✅ COPY pyproject.toml + uv.lock first, then uv sync, then COPY source code. Leverage Docker cache layers to avoid redundant installs
Error Troubleshooting Table
| Error | Possible Cause | Solution |
|---|---|---|
error: No virtual environment found |
Virtual environment not created | Run uv sync or uv venv to auto-create |
error: Failed to download package |
Network issue or PyPI unreachable | Configure mirror: uv pip config set global.index-url https://pypi.org/simple |
error: Python 3.12 not found |
Python version not installed | Run uv python install 3.12 |
error: Lockfile is out of date |
pyproject.toml updated without re-locking | Run uv lock to update the lock file |
error: Resolution failed |
Dependency version conflict | Check version constraints in pyproject.toml, use uv tree to view dependency tree |
error: Package not found in workspace |
Workspace member misconfigured | Check [tool.uv.workspace] members paths |
uv sync is slow |
Cache miss or network latency | Check cache directory permissions, configure mirror, use --offline mode |
error: Hash mismatch |
Package tampered or cache corrupted | Run uv cache clean and retry |
error: Cannot activate venv |
Virtual environment corrupted | Delete .venv directory and re-run uv sync |
error: Unsupported Python version |
Python version doesn't meet requires-python | Run uv python install to install a compatible version |
Advanced Optimization Tips
1. Mirror Acceleration
# Configure PyPI mirror
uv pip config set global.index-url https://pypi.org/simple
# Or configure in pyproject.toml
# [tool.uv]
# index-url = "https://pypi.org/simple"
# Multi-source configuration (private PyPI + public)
# [tool.uv]
# extra-index-url = ["https://pypi.mycompany.com/simple/"]
2. Cache Management
# View cache info
uv cache dir
uv cache list
# Clear cache
uv cache clean
# Clear cache for specific package
uv cache clean numpy
# View cache size
du -sh $(uv cache dir)
3. Offline Environment Deployment
# Export dependencies to vendor directory
uv export --no-dev > requirements.txt
uv pip download -r requirements.txt -d vendor/
# Offline install
uv pip install --no-index --find-links vendor/ -r requirements.txt
4. Script Inline Dependencies
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests>=2.32",
# "rich>=13.0",
# ]
# ///
import requests
from rich import print
response = requests.get("https://httpbin.org/json")
print(response.json())
# Run directly; uv auto-installs dependencies
uv run script.py
5. Dependency Security Audit
# Check known vulnerabilities
uv audit
Tool Comparison
| Dimension | uv | pip | poetry | pdm | conda |
|---|---|---|---|---|---|
| Resolution Speed | Extremely fast (Rust) | Slow (backtracking) | Medium | Fast | Slow |
| Virtual Env Management | Built-in | Requires venv | Built-in | Built-in | Built-in |
| Python Version Mgmt | Built-in | Requires pyenv | Requires pyenv | Built-in | Built-in |
| Lock File | uv.lock | None | poetry.lock | pdm.lock | None |
| Monorepo Support | Native workspace | No | No | Limited | No |
| CI Cache Friendly | Excellent | Fair | Good | Good | Poor |
| Configuration Complexity | Low | Low | High | Medium | High |
| Ecosystem Maturity | Rapidly growing | Most mature | Mature | Growing | Mature |
| Learning Curve | Gentle | Gentle | Steep | Medium | Steep |
| Package Count | Full PyPI | Full PyPI | Full PyPI | Full PyPI | Anaconda + PyPI |
| Cross-language Support | Python only | Python only | Python only | Python only | Multi-language (C/C++/R) |
| Recommendation | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
Selection Recommendations:
- New projects → uv (full-stack capability, blazing speed)
- Existing poetry projects → Gradually migrate to uv (compatible with poetry config)
- Data science/ML projects → uv + conda complement (uv for pure Python, conda for C/C++ deps)
- Simple scripts/one-off tasks → uv run (no project initialization needed)
Related Tools
In Python project development, these ToolsKu tools can help you:
- JSON Formatter — Format API responses and config files, debug JSON data in pyproject.toml
- Hash Calculator — Compute dependency package hashes, verify download integrity
- cURL to Code — Convert API requests to Python code in one click, quickly build HTTP clients
Python dependency management has evolved from
easy_installtopip, fromrequirements.txttopoetry.lock. uv is not simply a replacement -- it perfectly combines Rust's high performance with Python's ease of use, transforming dependency management from "a pain you have to endure" into "an experience that's nearly invisible". In 2026, uv is ready to be your default choice.
Try these browser-local tools — no sign-up required →