MeshWorld India Logo MeshWorld.
Cheatsheet Python uv Developer Tools Terminal Package Manager 12 min read

uv Cheat Sheet: The Fast Python Package Manager (2026)

Rachel
By Rachel
| Updated: May 21, 2026
uv Cheat Sheet: The Fast Python Package Manager (2026)
TL;DR
  • uv replaces pip, pip-tools, virtualenv, pyenv, and pipx — one tool for all of it
  • 10–100× faster than pip because it’s written in Rust and resolves in parallel
  • uv inituv add <pkg>uv run <script> is the full project workflow
  • uv python install 3.12 manages Python versions without pyenv
  • uvx <tool> runs CLI tools (like npx) without permanently installing them

Quick reference tables

Installation

| Method | Command | |---|---| | macOS / Linux (curl) | curl -LsSf https://astral.sh/uv/install.sh \| sh | | Windows (PowerShell) | powershell -c "irm https://astral.sh/uv/install.ps1 \| iex" | | Homebrew | brew install uv | | pip (if you must) | pip install uv | | Upgrade uv itself | uv self update |

Project workflow — most common commands

| Command | What it does | |---|---| | uv init myproject | Create a new project with pyproject.toml | | uv init --lib mylib | Create a library project (with src/ layout) | | uv add requests | Add a dependency and install it | | uv add "fastapi>=0.110" | Add with version constraint | | uv add --dev pytest | Add a dev-only dependency | | uv remove requests | Remove a dependency | | uv sync | Install all deps from uv.lock | | uv sync --frozen | Install exactly what’s in lockfile (CI use) | | uv lock | Update uv.lock without installing | | uv run python main.py | Run a script in the project venv | | uv run pytest | Run a tool installed in the project venv | | uv tree | Show full dependency tree |

Python version management

| Command | What it does | |---|---| | uv python list | Show available Python versions | | uv python install 3.12 | Download and install CPython 3.12 | | uv python install 3.11 3.12 3.13 | Install multiple versions | | uv python pin 3.12 | Pin project to Python 3.12 (writes .python-version) | | uv python find | Show path of the active Python | | uv python uninstall 3.11 | Remove a Python version |

Virtual environments

| Command | What it does | |---|---| | uv venv | Create .venv in current directory | | uv venv --python 3.12 | Create venv with specific Python | | uv venv myenv | Create venv with custom name | | source .venv/bin/activate | Activate (Linux/macOS) | | .venv\Scripts\activate | Activate (Windows) |

Skip Manual Activation

With uv run, you never need to activate the venv manually. uv run python and uv run pytest use the project venv automatically.

One-off tool execution (uvx)

uvx runs CLI tools from PyPI in isolated environments — equivalent to npx for Python:

| Command | What it does | |---|---| | uvx ruff check . | Run ruff linter without installing it | | uvx black . | Format with black | | uvx mypy src/ | Type-check with mypy | | uvx httpie GET https://api.example.com | HTTP client | | uvx --from 'ruff==0.4.0' ruff check . | Run a pinned version |

pip compatibility mode

If you need pip syntax (scripts, Docker layers, CI), uv supports it:

| Command | What it does | |---|---| | uv pip install requests | Same as pip install requests | | uv pip install -r requirements.txt | Install from requirements file | | uv pip freeze | Print installed packages | | uv pip list | List installed packages (table) | | uv pip show requests | Package metadata | | uv pip compile requirements.in | Pin deps to requirements.txt | | uv pip sync requirements.txt | Sync venv to exact requirements file |


Project structure

When you run uv init myproject, you get:

plaintext
myproject/
├── pyproject.toml      # Project metadata and dependencies
├── uv.lock             # Exact locked versions (commit this)
├── .python-version     # Python version pin (commit this)
├── .venv/              # Virtual environment (gitignore this)
└── src/
    └── myproject/
        └── __init__.py

A typical pyproject.toml managed by uv:

toml
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.110",
    "httpx>=0.27",
]

[dependency-groups]
dev = [
    "pytest>=8",
    "ruff>=0.4",
    "mypy>=1.10",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

Common workflows

Starting a new project from scratch

bash
uv init myapi              # Create project
cd myapi

uv python pin 3.12         # Pin Python version

uv add fastapi uvicorn     # Add runtime deps
uv add --dev pytest ruff   # Add dev deps

uv run uvicorn main:app --reload   # Run without activating venv

Adding dependencies with version constraints

bash
uv add "sqlalchemy>=2.0,<3"   # Range constraint
uv add "pydantic==2.7.*"      # Wildcard patch
uv add "numpy ; python_version>='3.10'"  # Conditional
uv add "torch --index https://download.pytorch.org/whl/cu121"  # Custom index

Running scripts without a project

For quick one-off scripts, uv run works without uv init:

bash
# Script with inline dependency metadata (PEP 723)
cat > script.py << 'EOF'
# /// script
# requires-python = ">=3.11"
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
print(requests.get("https://httpbin.org/get").json())
EOF

uv run script.py    # uv installs deps in isolated env, then runs it

CI/CD — fast, reproducible installs

bash
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install project deps from lockfile (no resolver overhead)
uv sync --frozen

# Run tests
uv run pytest

GitHub Actions shorthand:

yaml
- uses: astral-sh/setup-uv@v4
- run: uv sync --frozen
- run: uv run pytest

Migration cheat sheet — pip / poetry / pyenv → uv

| Old tool | Old command | uv equivalent | |---|---|---| | pip | pip install requests | uv add requests | | pip | pip install -r requirements.txt | uv pip install -r requirements.txt | | pip | pip freeze > requirements.txt | uv pip freeze > requirements.txt | | pip-tools | pip-compile requirements.in | uv pip compile requirements.in | | pip-tools | pip-sync requirements.txt | uv pip sync requirements.txt | | poetry | poetry new myproject | uv init myproject | | poetry | poetry add requests | uv add requests | | poetry | poetry add --group dev pytest | uv add --dev pytest | | poetry | poetry install | uv sync | | poetry | poetry run pytest | uv run pytest | | poetry | poetry lock | uv lock | | poetry | poetry shell | source .venv/bin/activate | | pyenv | pyenv install 3.12 | uv python install 3.12 | | pyenv | pyenv local 3.12 | uv python pin 3.12 | | pyenv | pyenv versions | uv python list | | pipx | pipx install ruff | uvx ruff (no install needed) | | pipx | pipx run black . | uvx black . | | virtualenv | python -m venv .venv | uv venv |

uv.lock is not requirements.txt

uv.lock is a cross-platform, human-readable lockfile — commit it to version control. Never hand-edit it. If a teammate on Windows and you on macOS both run uv sync --frozen, you both get the same logical packages but the right platform-specific wheels.


Speed comparison

| Task | pip | uv | |---|---|---| | Install Django cold | ~8s | ~0.3s | | Install Django cached | ~3s | ~0.05s | | Resolve 200 deps | ~45s | ~1.2s | | Create virtualenv | ~1.2s | ~0.05s |

uv downloads wheels in parallel, uses a global content-addressable cache, and avoids redundant resolver passes. The cache is stored at ~/.cache/uv (Linux/macOS) or %LOCALAPPDATA%\uv\cache (Windows).


Global tools and uv tool

uv tool manages globally installed CLI tools — separate from project dependencies:

| Command | What it does | |---|---| | uv tool install ruff | Install ruff globally (adds to PATH) | | uv tool install --python 3.12 ruff | Install with a specific Python | | uv tool upgrade ruff | Upgrade a global tool | | uv tool list | Show globally installed tools | | uv tool upgrade-all | Upgrade all global tools | | uv tool uninstall ruff | Remove a global tool |

Tools installed via uv tool are placed in ~/.local/bin/uv-tools/ (Linux/macOS) or %LOCALAPPDATA%\uv\tools\ (Windows). Add that directory to your PATH to use them from anywhere.

uvx vs uv tool install

Use uvx for one-off runs (always gets latest version). Use uv tool install when you want a persistent, pinned installation accessible from any shell.


Workspaces and monorepos

uv supports workspaces — a single pyproject.toml at the root with multiple packages beneath it:

plaintext
myorg/
├── pyproject.toml        # Workspace root
├── packages/
│   ├── core/
│   │   ├── pyproject.toml
│   │   └── src/core/
│   └── api/
│       ├── pyproject.toml
│       └── src/api/
├── uv.lock               # Single lockfile for all packages
└── .python-version

Root pyproject.toml:

toml
[workspace]
members = ["packages/core", "packages/api"]

[tool.uv.workspace]
bash
uv sync              # Sync all workspace packages
uv sync --all-packages  # Include all members
uv add --package api requests  # Add to specific package
uv run --package api uvicorn   # Run from specific package

Lockfile deep dive

uv.lock is a human-readable, human-editable lockfile. Key sections:

toml
[[package]]
name = "fastapi"
version = "0.115.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
    { url = "https://files.pythonhosted.org/packages/.../fastapi-0.115.0-py3-none-any.whl" },
]
  • Platform-specific wheels — uv picks the right wheel for Linux/macOS/Windows automatically
  • No source distribution builds — uv avoids compiling from source unless necessary
  • Reproducible across machines — two people on different OSes get the same logical packages
  • Commit ituv.lock goes into version control; .venv/ goes into .gitignore
bash
uv lock --upgrade          # Upgrade all packages to latest
uv lock --upgrade-package fastapi  # Upgrade specific package
uv lock --verify           # Verify lockfile matches pyproject.toml

Real-world project examples

FastAPI API project

bash
uv init myapi
cd myapi

uv python pin 3.13
uv add fastapi "uvicorn[standard]" sqlalchemy pydantic-settings
uv add --dev pytest httpx

uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000

Data science notebook setup

bash
uv init ds-project --lib
cd ds-project

uv python pin 3.12
uv add numpy pandas matplotlib jupyterlab
uv add --dev ruff mypy

uv run jupyter lab

Script with inline dependencies (no project needed)

bash
# Create a standalone script with its own dependencies
cat > analyze.py << 'EOF'
# /// script
# requires-python = ">=3.11"
# dependencies = ["pandas", "plotly", "typer"]
# ///
import pandas as pd
import plotly.express as px
import typer

def main(csv_path: str):
    df = pd.read_csv(csv_path)
    px.histogram(df).show()

if __name__ == "__main__":
    typer.run(main)
EOF

uv run analyze.py data.csv

Cross-platform notes

| Platform | Cache location | Tool location | |---|---|---| | Linux | ~/.cache/uv/ | ~/.local/bin/ | | macOS | ~/.cache/uv/ | ~/.local/bin/ | | Windows | %LOCALAPPDATA%\uv\cache\ | %LOCALAPPDATA%\uv\tools\ |

On Linux/macOS, add ~/.local/bin to PATH. On Windows, add %LOCALAPPDATA%\uv\tools\ to PATH.

bash
# Linux / macOS — add to ~/.bashrc or ~/.zshrc
export PATH="$HOME/.local/bin:$PATH"

# Verify uv is found
which uv
uv --version

Troubleshooting

Permission errors on macOS (SIP)

macOS restricts writing to /usr/local. Use brew install uv or the official installer (which installs to $HOME/.local/bin):

bash
curl -LsSf https://astral.sh/uv/install.sh | sh

Windows: “uv is not recognized”

The installer should add to PATH automatically. If not, manually add %USERPROFILE%\.local\bin\ to your system PATH.

”Python version not found”

bash
uv python list  # Shows available versions
uv python install 3.12  # Install missing version

Lockfile out of sync

bash
uv sync           # Auto-updates lockfile if needed
uv lock --check  # Fails if lockfile is stale

Slow first install

uv downloads wheels in parallel. If you’re behind a slow proxy or VPN, try:

bash
UV_HTTP_TIMEOUT=60 uv sync

Summary

  • One tool replaces the entire Python toolchain: pip + pip-tools + virtualenv + pyenv + pipx
  • uv add / uv remove manages pyproject.toml and uv.lock automatically
  • uv run executes in the right environment without manual activation
  • uvx runs any PyPI CLI tool ephemerally — no global installs needed
  • uv sync --frozen is the CI command — fast, reproducible, no network surprises
  • Workspaces enable monorepo support with a single lockfile
  • uv tool install provides persistent global tools; uvx for one-off runs

FAQ

Does uv work with existing requirements.txt projects? Yes. uv pip install -r requirements.txt is a drop-in replacement for pip install -r requirements.txt. Migrate to pyproject.toml at your own pace.

Should I commit uv.lock? Yes, always commit uv.lock for applications. For libraries, commit it for reproducible CI but do not publish it to PyPI. This matches the poetry.lock convention.

Does uv support private PyPI servers (Artifactory, Nexus)? Yes. Set [[tool.uv.index]] in pyproject.toml or use --index-url and --extra-index-url flags.

What Python distributions does uv install? CPython from python-build-standalone (Greg Price / Astral) by default. These are statically linked, fast-starting binaries. PyPy support is on the roadmap.

Is uv production-stable? As of 2025, uv is used by major projects including Ruff, Pydantic, FastAPI, and Astral’s own tooling. Astral backs it commercially. It follows semver and has a stability policy.