uv
uv is an extremely fast Python package and project manager written in Rust. It replaces pip, pip-tools, pipx, pyenv, virtualenv, and poetry.
When to Use uv
Always use uv for Python work, especially if you see:
- •The
uv.lockfile - •uv headers in
requirements*files ("This file was autogenerated by uv")
Don't use uv in projects managed by other tools:
- •Poetry projects (
poetry.lock) - •PDM projects (
pdm.lock)
Workflows
Scripts
Use when: Running single Python files and standalone scripts.
uv run script.py # Run a script uv run --with requests script.py # Run with additional packages uv add --script script.py requests # Add inline dependencies to script
Projects
Use when: There is a pyproject.toml or uv.lock
uv init # Create new project uv add requests # Add dependency uv add --dev pytest # Add dev dependency uv remove requests # Remove dependency uv sync # Install from lockfile uv run <command> # Run in project environment uv run python -c "" # Run Python in project environment uv run -p 3.12 <command> # Run with specific Python version
Tools
Use when: Running CLI tools (ruff, pytest, mypy) without installation.
uvx <tool> <args> # Run tool without installation uvx <tool>@<version> <args> # Run specific version uvx ruff check . # Example: run ruff
Important: Only use uv tool install when explicitly requested.
Pip Interface
Use when: Legacy workflows with requirements.txt, no uv.lock present.
uv venv # Create virtual environment uv pip install -r requirements.txt # Install from requirements uv pip compile requirements.in -o requirements.txt # Compile deps uv pip sync requirements.txt # Sync environment uv pip compile --universal requirements.in -o requirements.txt # Cross-platform
Prefer uv init for new projects over pip interface.
Workspaces
Workspaces manage multiple related packages in a monorepo structure.
Configuration
# Root pyproject.toml
[tool.uv.workspace]
members = ["packages/*", "apps/*"]
exclude = ["packages/legacy"]
[tool.uv.sources]
# Local package references
mylib = { workspace = true }
shared = { path = "../shared", editable = true }
# Git sources
mypackage = { git = "https://github.com/org/repo", branch = "main" }
Structure
my-workspace/
├── pyproject.toml # Root workspace config
├── uv.lock # Single lockfile for all packages
├── packages/
│ ├── core/
│ │ └── pyproject.toml # [project] with dependencies
│ └── utils/
│ └── pyproject.toml
└── apps/
└── api/
└── pyproject.toml
Commands
uv sync # Sync all workspace packages uv sync --package myapp # Sync specific package uv run --package myapp pytest # Run in specific package context uv add requests --package myapp # Add dep to specific package uv lock # Update workspace lockfile
Cross-Package Dependencies
# apps/api/pyproject.toml
[project]
dependencies = ["core", "utils"]
[tool.uv.sources]
core = { workspace = true }
utils = { workspace = true }
Python Version Management
uv python install 3.12 # Install Python version uv python list --only-installed # List installed versions uv python pin 3.12 # Pin version for project uv python install 3.12 --default # Set as system default
Common Patterns
Don't use pip in uv projects
# ❌ Bad uv pip install requests # ✅ Good uv add requests
Don't run python directly
# ❌ Bad python script.py python -c "..." # ✅ Good uv run script.py uv run python -c "..."
Don't manually manage environments
# ❌ Bad python -m venv .venv source .venv/bin/activate # ✅ Good uv run <command>
Running with specific Python
# ❌ Bad python3.12 -c "..." # ✅ Good uvx python@3.12 -c "..." uv run -p 3.12 <command>
Migration
From pyenv
pyenv install 3.12 → uv python install 3.12 pyenv versions → uv python list --only-installed pyenv local 3.12 → uv python pin 3.12 pyenv global 3.12 → uv python install 3.12 --default
From pipx
pipx run ruff → uvx ruff pipx install ruff → uv tool install ruff pipx upgrade ruff → uv tool upgrade ruff pipx list → uv tool list
From pip/pip-tools
pip install package → uv pip install package pip-compile req.in → uv pip compile req.in pip-sync req.txt → uv pip sync req.txt virtualenv .venv → uv venv
Best Practices
Project Setup:
- •Use
uv initfor new projects - •Use
uv addfor dependencies (not pip install) - •Commit
uv.lockto version control - •Use
uv syncto reproduce environments
Workspaces:
- •Define members with glob patterns:
packages/* - •Use
workspace = truefor internal dependencies - •Single
uv.lockat root manages all packages - •Run commands with
--packagefor specific contexts
Scripts:
- •Use
uv run script.pyinstead ofpython script.py - •Use
--withfor ad-hoc dependencies - •Use
uv add --scriptfor persistent script dependencies