uv (Astral) cheatsheet — Python’s fastest packaging tool in 2026.

Install

curl -LsSf https://astral.sh/uv/install.sh | sh
# or
brew install uv

Create project

uv init myapp
cd myapp

Creates pyproject.toml, .python-version, src/myapp/.

Add deps

uv add fastapi pydantic sqlalchemy[asyncio]
uv add --dev pytest pytest-anyio httpx ruff mypy
uv add 'pydantic>=2.5,<3'
uv add 'requests; python_version < "3.13"'
uv add -e ../my-other-package          # editable
uv add git+https://github.com/x/y.git

Remove deps

uv remove requests

Sync (install lock)

uv sync                       # all deps from uv.lock
uv sync --frozen              # error if lock would change (CI)
uv sync --no-dev              # skip dev deps
uv sync --group docs          # specific group

Lock

uv lock                       # regenerate uv.lock
uv lock --upgrade             # upgrade all
uv lock --upgrade-package pydantic

Run

uv run python main.py
uv run pytest
uv run ruff check
uv run --with httpx python script.py     # one-off dep

Python version management

uv python list
uv python install 3.13
uv python pin 3.13           # writes .python-version
uv python find

Tool install (replace pipx)

uv tool install ruff
uv tool install black
uv tool install ipython
uv tool list
uv tool upgrade --all
uv tool run pytest           # without installing

Or shorter:

uvx pytest                   # tool run
uvx --with httpx python -c "import httpx; print(httpx.__version__)"

pyproject.toml structure

[project]
name = "myapp"
version = "0.1.0"
description = "..."
authors = [{name = "Me"}]
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "fastapi>=0.115",
    "pydantic>=2.9",
]

[dependency-groups]
dev = ["pytest", "ruff"]
docs = ["mkdocs", "mkdocs-material"]

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

[tool.uv]
package = true            # treats project as installable

Workspaces (monorepo)

[tool.uv.workspace]
members = ["packages/*", "apps/*"]

Each package has its own pyproject; uv links them.

Sources (override registry per dep)

[tool.uv.sources]
mypackage = { git = "https://github.com/me/mypackage", rev = "main" }
local-pkg = { path = "../local-pkg" }

Build a wheel

uv build                     # creates dist/*.whl + *.tar.gz
uv build --sdist
uv build --wheel

Publish

uv publish                   # to PyPI
uv publish --index test-pypi

Cache

uv cache dir
uv cache clean
uv cache prune --ci          # CI-friendly prune

Pip-compatible interface

uv pip install requests       # like pip install
uv pip list
uv pip freeze
uv pip uninstall requests

For legacy workflows; project workflow (uv add) is preferred.

.python-version

3.13

uv auto-detects and uses this. Per-project Python version.

Inline script deps (PEP 723)

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.13"
# dependencies = ["httpx", "rich"]
# ///

import httpx
from rich import print
print(httpx.get("https://example.com").status_code)

Run:

uv run script.py

Self-contained scripts; uv installs deps on demand.

CI

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

Cache-friendly:

- uses: astral-sh/setup-uv@v3
  with:
    enable-cache: true

Common patterns

# Bootstrap new project
uv init myapp && cd myapp
uv add fastapi 'pydantic[email]>=2.5'
uv add --dev pytest pytest-anyio httpx ruff mypy
uv run uvicorn src.myapp.main:app --reload

# Run formatter / linter
uv run ruff format .
uv run ruff check . --fix
uv run mypy src

# Update one dep
uv add 'pydantic>=2.10'
uv sync

Why uv

  • 10-100× faster than pip / poetry.
  • One tool: venvs, lockfile, Python install, tool install, scripts.
  • Drop-in compatible with pip install ... via uv pip.

Common mistakes

  • Mixing pip install and uv sync in same env — drift.
  • Forgetting --frozen in CI — non-reproducible.
  • Committing the venv (.venv/) — don’t.
  • Not committing uv.lock — non-reproducible builds.

Read this next

If you want my uv-based project starter, it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .