MeshWorld India LogoMeshWorld.
CheatsheetPythonuvDeveloper ToolsTerminalPackage Manager12 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

MethodCommand
macOS / Linux (curl)curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell)powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Homebrewbrew install uv
pip (if you must)pip install uv
Upgrade uv itselfuv self update

Project workflow — most common commands

CommandWhat it does
uv init myprojectCreate a new project with pyproject.toml
uv init --lib mylibCreate a library project (with src/ layout)
uv add requestsAdd a dependency and install it
uv add "fastapi>=0.110"Add with version constraint
uv add --dev pytestAdd a dev-only dependency
uv remove requestsRemove a dependency
uv syncInstall all deps from uv.lock
uv sync --frozenInstall exactly what’s in lockfile (CI use)
uv lockUpdate uv.lock without installing
uv run python main.pyRun a script in the project venv
uv run pytestRun a tool installed in the project venv
uv treeShow full dependency tree

Python version management

CommandWhat it does
uv python listShow available Python versions
uv python install 3.12Download and install CPython 3.12
uv python install 3.11 3.12 3.13Install multiple versions
uv python pin 3.12Pin project to Python 3.12 (writes .python-version)
uv python findShow path of the active Python
uv python uninstall 3.11Remove a Python version

Virtual environments

CommandWhat it does
uv venvCreate .venv in current directory
uv venv --python 3.12Create venv with specific Python
uv venv myenvCreate venv with custom name
source .venv/bin/activateActivate (Linux/macOS)
.venv\Scripts\activateActivate (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:

CommandWhat 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.comHTTP 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:

CommandWhat it does
uv pip install requestsSame as pip install requests
uv pip install -r requirements.txtInstall from requirements file
uv pip freezePrint installed packages
uv pip listList installed packages (table)
uv pip show requestsPackage metadata
uv pip compile requirements.inPin deps to requirements.txt
uv pip sync requirements.txtSync 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 toolOld commanduv equivalent
pippip install requestsuv add requests
pippip install -r requirements.txtuv pip install -r requirements.txt
pippip freeze > requirements.txtuv pip freeze > requirements.txt
pip-toolspip-compile requirements.inuv pip compile requirements.in
pip-toolspip-sync requirements.txtuv pip sync requirements.txt
poetrypoetry new myprojectuv init myproject
poetrypoetry add requestsuv add requests
poetrypoetry add --group dev pytestuv add --dev pytest
poetrypoetry installuv sync
poetrypoetry run pytestuv run pytest
poetrypoetry lockuv lock
poetrypoetry shellsource .venv/bin/activate
pyenvpyenv install 3.12uv python install 3.12
pyenvpyenv local 3.12uv python pin 3.12
pyenvpyenv versionsuv python list
pipxpipx install ruffuvx ruff (no install needed)
pipxpipx run black .uvx black .
virtualenvpython -m venv .venvuv 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

Taskpipuv
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:

CommandWhat it does
uv tool install ruffInstall ruff globally (adds to PATH)
uv tool install --python 3.12 ruffInstall with a specific Python
uv tool upgrade ruffUpgrade a global tool
uv tool listShow globally installed tools
uv tool upgrade-allUpgrade all global tools
uv tool uninstall ruffRemove 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

PlatformCache locationTool 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.


Share_This Twitter / X
Rachel
Written By

Rachel

Senior Full-stack Developer specializing in backend systems. Expert in database optimization, asynchronous programming in Python, and building resilient API architectures.

Enjoyed this article?

Support MeshWorld and help us create more technical content