Use when working with uv — Python package and project manager. Covers project setup, dependency management, workspaces, scripts, tool management, Python version management, CI integration, and Docker.
Modern Python package and project manager. Replaces pip, pip-tools, virtualenv, pyenv, poetry, and pipx.
# New project
uv init myproject
cd myproject
# New project with package structure (src layout)
uv init myproject --package
cd myproject
# In an existing directory
uv init
Creates pyproject.toml, .python-version, and hello.py.
# Add a runtime dependency
uv add httpx pydantic
# Add a dev dependency
uv add --dev pytest ruff mypy
# Add an optional dependency group
uv add --group lint ruff mypy
# Add with version constraint
uv add "fastapi>=0.100" "sqlalchemy>=2.0,<3"
# Remove a dependency
uv remove httpx
# Sync installed packages to match lock file (after git pull, etc.)
uv sync
# Sync including dev dependencies
uv sync --dev
# Sync a specific group
uv sync --group lint
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.100",
"pydantic>=2",
"sqlalchemy>=2",
]
[project.optional-dependencies]
# Use [dependency-groups] instead for dev tools (uv convention)
[dependency-groups]
dev = [
"pytest>=8",
"ruff>=0.6",
"mypy>=1.8",
]
lint = [
"ruff>=0.6",
"mypy>=1.8",
]
[project.scripts]
myapp = "myproject.cli:app"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# Run in the project's virtual environment
uv run python script.py
uv run pytest
uv run myapp
# Run without installing in the venv first (useful for tools)
uv run --with httpx python -c "import httpx; print(httpx.get('https://httpbin.org/get'))"
# Open a Python shell in the venv
uv run python
# Install a Python version
uv python install 3.12
uv python install 3.11 3.12 3.13
# List available and installed versions
uv python list
# Pin the project to a version (writes .python-version)
uv python pin 3.12
# Use a specific version for a command
uv run --python 3.11 pytest
.python-version is respected by uv automatically.
uv.lock is generated automatically by uv add/uv sync. Always commit it.
# Update all dependencies to latest compatible versions
uv lock --upgrade
# Update a specific package
uv lock --upgrade-package httpx
# Check if lock file is up to date (useful in CI)
uv lock --check
Run a script with its own dependencies without a project:
uv run script.py
# script.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx",
# "rich",
# ]
# ///
import httpx
from rich import print
response = httpx.get("https://api.github.com")
print(response.json())
# Run directly with uv
uv run script.py
# Run from a URL
uv run https://gist.github.com/.../script.py
# Install a tool globally (isolated env, like pipx)
uv tool install ruff
uv tool install black
uv tool install httpie
# Run a tool without installing permanently
uvx ruff check .
uvx black .
uvx --with git+https://github.com/me/mytool mytool install
# List installed tools
uv tool list
# Upgrade a tool
uv tool upgrade ruff
# Uninstall a tool
uv tool uninstall black
# Root pyproject.toml
[tool.uv.workspace]
members = ["packages/*", "apps/*"]
myrepo/
├── pyproject.toml # workspace root
├── uv.lock # single lock file for all packages
├── packages/
│ ├── shared/
│ │ └── pyproject.toml
│ └── models/
│ └── pyproject.toml
└── apps/
├── api/
│ └── pyproject.toml
└── worker/
└── pyproject.toml
Member packages can depend on each other:
# apps/api/pyproject.toml
[project]
dependencies = [
"shared", # refers to packages/shared in the workspace
"models",
]
[tool.uv.sources]
shared = { workspace = true }
models = { workspace = true }
# Sync the whole workspace
uv sync
# Run in a specific workspace member
uv run --package api uvicorn api.main:app
[tool.uv.sources]
# Git dependency
mylib = { git = "https://github.com/me/mylib", rev = "main" }
# Local path dependency
mylib = { path = "../mylib", editable = true }
# Alternative index
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true # cache the uv cache dir between runs
python-version: "3.12" # installs Python too
- run: uv sync --frozen # --frozen: fail if lock file is out of date
- run: uv run pytest
- run: uv run ruff check .