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.lock file
-
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 init for new projects
-
Use uv add for dependencies (not pip install)
-
Commit uv.lock to version control
-
Use uv sync to reproduce environments
Workspaces:
-
Define members with glob patterns: packages/*
-
Use workspace = true for internal dependencies
-
Single uv.lock at root manages all packages
-
Run commands with --package for specific contexts
Scripts:
-
Use uv run script.py instead of python script.py
-
Use --with for ad-hoc dependencies
-
Use uv add --script for persistent script dependencies
Documentation