Ir al contenido

uv

Overview

uv is a modern Python package and project manager from Astral, written in Rust and designed to be 10–100x faster than pip. It provides a unified interface for managing Python versions, virtual environments, project dependencies, lockfiles, and standalone tools — replacing pip, pip-tools, pipx, poetry, pyenv, and virtualenv in one binary.

Installation

curl -LsSf https://astral.sh/uv/install.sh | sh
# Or via pip
pip install uv

Windows (PowerShell)

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Homebrew (macOS / Linux)

brew install uv

Verify installation

uv --version
uv self update   # Update uv itself

Configuration

Environment variables

UV_PYTHON=3.12          # Default Python version
UV_CACHE_DIR=~/.cache/uv  # Custom cache location
UV_NO_CACHE=1           # Disable caching
UV_INDEX_URL=https://pypi.org/simple  # Custom index
UV_EXTRA_INDEX_URL=https://my.pypi.org/simple  # Additional index
UV_SYSTEM_PYTHON=1      # Allow using system Python
UV_LINK_MODE=copy       # hardlink | symlink | copy | clone

uv.toml (project-level config)

[tool.uv]
python = "3.12"
index-url = "https://pypi.org/simple"

[[tool.uv.index]]
name = "internal"
url = "https://internal.company.com/simple"

pyproject.toml integration

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "fastapi>=0.110",
    "httpx>=0.27",
]

[project.optional-dependencies]
dev = ["pytest", "ruff"]

[tool.uv]
dev-dependencies = ["pytest>=8", "ruff>=0.4"]

Core Commands

CommandDescription
uv init my-projectCreate a new project with pyproject.toml
uv add requestsAdd a dependency and update lockfile
uv add --dev pytestAdd a dev dependency
uv remove requestsRemove a dependency
uv syncInstall all dependencies from lockfile
uv lockGenerate/update uv.lock without installing
uv run python script.pyRun script in project virtual environment
uv run pytestRun a command in the project environment
uv pip install requestspip-compatible install
uv pip compile requirements.inCompile requirements like pip-tools
uv pip sync requirements.txtSync environment to requirements file
uv venvCreate a virtual environment
uv python install 3.12Download and install Python 3.12
uv python listList available Python versions
uv python pin 3.11Pin project to Python version
uv tool install ruffInstall a CLI tool globally
uv tool run ruff check .Run a tool without installing
uvx ruff check .Shorthand for uv tool run
uv treeShow dependency tree
uv exportExport dependencies to requirements.txt

Advanced Usage

Python version management

# Install specific Python versions
uv python install 3.11 3.12 3.13

# List installed and available versions
uv python list

# Pin a project to a version (writes .python-version)
uv python pin 3.12

# Use a specific version for a command
uv run --python 3.11 python --version

# Find the Python interpreter uv would use
uv python find 3.12

Virtual environment control

# Create venv in default .venv/
uv venv

# Create venv with specific Python
uv venv --python 3.12

# Create venv in custom location
uv venv /path/to/myenv

# Activate (standard shell activation still works)
source .venv/bin/activate

# Or just use uv run to avoid activating
uv run python -c "import sys; print(sys.version)"

Lockfile and reproducible builds

# Generate lockfile without installing
uv lock

# Install exactly what's in the lockfile
uv sync --frozen

# Check lockfile is up-to-date (CI use)
uv lock --check

# Export to pip-compatible requirements
uv export --format requirements-txt > requirements.txt
uv export --no-hashes > requirements.txt
uv export --only-dev > dev-requirements.txt

Workspace (monorepo) support

# Root pyproject.toml
[tool.uv.workspace]
members = ["packages/*"]
# Sync entire workspace
uv sync --all-packages

# Sync a specific member
uv sync --package my-lib

Dependency groups and extras

# Add with extras
uv add "fastapi[standard]"

# Sync with optional extras
uv sync --extra all

# Add to a named group
uv add --group lint ruff mypy

# Sync only specific groups
uv sync --group dev --group lint

Tool management (replaces pipx)

# Install tool globally
uv tool install ruff
uv tool install black
uv tool install httpie

# List installed tools
uv tool list

# Run a tool without permanent install
uvx cowsay "hello"

# Upgrade a tool
uv tool upgrade ruff

# Uninstall a tool
uv tool uninstall ruff

# Install specific version of a tool
uv tool install ruff==0.4.0

Advanced pip interface

CommandDescription
uv pip install -r requirements.txtInstall from requirements file
uv pip install -e .Editable install
uv pip install --index-url URL pkgInstall from custom index
uv pip listList installed packages
uv pip show requestsShow package details
uv pip freezeOutput installed packages
uv pip checkCheck for dependency conflicts
uv pip uninstall requestsUninstall a package
uv pip compile pyproject.toml -o requirements.txtCompile dependencies
uv pip sync requirements.txtSync environment exactly

Common Workflows

Starting a new project

# Initialize project
uv init my-api
cd my-api

# Add dependencies
uv add fastapi uvicorn httpx
uv add --dev pytest pytest-asyncio ruff

# Run the application
uv run uvicorn main:app --reload

# Run tests
uv run pytest

Migrating from pip / requirements.txt

# Convert requirements.txt to pyproject.toml-managed project
uv init --no-readme
uv add $(cat requirements.txt | grep -v '^#' | tr '\n' ' ')

# Or keep using requirements.txt with uv's pip interface
uv pip install -r requirements.txt

Migrating from poetry

# uv reads pyproject.toml natively
# Just replace `poetry install` with:
uv sync

# Replace `poetry add X` with:
uv add X

# Replace `poetry run X` with:
uv run X

CI/CD (GitHub Actions)

- uses: astral-sh/setup-uv@v5
  with:
    version: "latest"
    enable-cache: true

- name: Install dependencies
  run: uv sync --frozen

- name: Run tests
  run: uv run pytest

Docker usage

FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

COPY . .
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0"]

Scripting with inline dependencies

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

import httpx
from rich import print

data = httpx.get("https://api.github.com").json()
print(data)
uv run my_script.py  # uv installs deps automatically
chmod +x my_script.py && ./my_script.py

Tips and Best Practices

Commit the lockfile. Always commit uv.lock to version control for reproducible installs across your team and CI.

Use uv sync --frozen in CI. This fails if the lockfile is out of date, preventing accidental dependency drift in production.

Prefer uv run over activating the venv. Running uv run pytest instead of activating .venv is more portable and works in scripts without shell magic.

Cache in CI. Use astral-sh/setup-uv with enable-cache: true for fast GitHub Actions runs. uv caches downloaded wheels and metadata aggressively.

Use uvx for one-off tools. Instead of globally installing linters or generators just to run them once, use uvx ruff check . — it downloads, caches, and runs without polluting your environment.

Separate dev dependencies from production. Use uv add --dev or --group to keep production images lean. Then uv sync --no-dev in Docker.

Pin Python version in .python-version. Run uv python pin 3.12 to create this file so all teammates and CI use the same interpreter without extra config.

Use workspaces for monorepos. If you have multiple related packages, uv workspaces let you share a single lockfile and avoid duplicating dependencies.

Check for outdated packages. Use uv tree --outdated to see which dependencies have newer versions available before running uv lock --upgrade.

Speed comparison. uv is typically 10–100x faster than pip for cold installs and near-instant for cached installs. The Rust implementation eliminates Python overhead in the resolver.