Standardize Python development using UV - a fast, unified package and project manager.
UV is the modern standard for Python package and project management in 2025, delivering 10-100x speed improvements while unifying pip, virtualenv, pyenv, poetry, and pipx into a single Rust-based tool.
Use this skill when:
uv init and uv add instead of manual configurationuv.lock for reproducibilityuv run instead of manual environment activation.python-version for team consistency# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows PowerShell
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Update UV
uv self update
# Initialize project (creates pyproject.toml, .python-version, .gitignore)
uv init my-project
cd my-project
# Add dependencies
uv add requests fastapi pandas
# Add development dependencies
uv add --dev pytest ruff mypy
# Add to custom groups
uv add --group docs sphinx
uv add --group test pytest-cov
# Run code (auto-syncs environment)
uv run python main.py
uv run pytest
uv init [name] # Create new project with structure
uv add <package> # Add dependency (updates pyproject.toml + uv.lock)
uv add --dev <package> # Add development dependency
uv add --group <name> <pkg> # Add to custom dependency group
uv remove <package> # Remove dependency
uv sync # Install/sync all dependencies
uv sync --frozen # Sync without updating lock (CI mode)
uv sync --no-dev # Production install (exclude dev deps)
uv run <command> # Run command in project environment
uv build # Build distribution packages
uv publish # Publish to PyPI
uv python install 3.12 # Install Python version
uv python install 3.11 3.12 # Install multiple versions
uv python list # List installed Python versions
uv python pin 3.12 # Pin project to Python version
uv python find # Show active Python version
uv venv # Create virtual environment (.venv/)
uv venv --python 3.12 # Create with specific Python version
uv venv my-env # Create with custom name
uv lock # Update lockfile from pyproject.toml
uv lock --upgrade # Upgrade all dependencies
uv lock --upgrade-package <pkg> # Upgrade specific package
uv lock --check # Verify lock is current (CI check)
uv export --format requirements-txt > requirements.txt # Export format
uvx <tool> # Run tool temporarily (no install)
uvx ruff check . # Example: run ruff once
uv tool install <tool> # Install tool globally
uv tool list # List installed tools
uv tool uninstall <tool> # Remove global tool
uv cache clean # Clean cache
uv cache dir # Show cache location
uv self update # Update UV itself
project/
├── .git/
├── .gitignore # Auto-generated by uv init
├── .python-version # Python version pin (COMMIT THIS)
├── README.md # Setup instructions
├── pyproject.toml # Project configuration (COMMIT THIS)
├── uv.lock # Universal lockfile (COMMIT THIS)
├── .venv/ # Virtual environment (DO NOT COMMIT)
├── src/
│ └── package/
│ ├── __init__.py
│ └── main.py
└── tests/
└── test_main.py
[project]
name = "my-app"
version = "0.1.0"
description = "Application description"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"requests>=2.31.0,<3.0.0", # Range with upper bound
"pandas>=2.0.0", # Minimum version
"fastapi[standard]>=0.115.0", # With extras
]
[project.optional-dependencies]
plotting = ["matplotlib>=3.7.0", "seaborn>=0.12.0"]
database = ["sqlalchemy>=2.0.0", "psycopg2-binary>=2.9.0"]
[dependency-groups]
dev = ["pytest>=8.0.0", "ruff>=0.3.0", "mypy>=1.8.0"]
test = ["pytest-cov>=4.1.0", "pytest-asyncio>=0.23.0"]
docs = ["sphinx>=7.0.0", "sphinx-rtd-theme>=2.0.0"]
Adding dependencies:
# Single package
uv add requests
# Multiple packages
uv add requests pandas numpy
# With version constraints
uv add "fastapi>=0.115.0,<1.0.0"
# With extras
uv add "fastapi[standard]"
# Development dependencies
uv add --dev pytest ruff mypy
# Optional dependency groups
uv add --optional plotting matplotlib seaborn
Managing versions:
# Upgrade all dependencies
uv lock --upgrade
# Upgrade specific package
uv lock --upgrade-package requests
# Pin to latest compatible versions
uv add requests --upgrade
Always use uv run instead of activating environments:
# Run Python scripts
uv run python script.py
uv run python -m mymodule
# Run installed tools
uv run pytest
uv run ruff check .
uv run mypy src/
# Run with specific Python version
uv run --python 3.12 python script.py
# Pass arguments
uv run pytest tests/ -v --cov
Why uv run is better:
Create portable single-file scripts:
#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "requests",
# "rich",
# ]
# ///
import requests
from rich import print
response = requests.get("https://api.github.com")
print(response.json())
Run with: uv run script.py (automatically installs dependencies)
Project-level pinning:
# Pin Python version for project
uv python pin 3.12
# This creates .python-version file
# Always commit this file to git
# UV will automatically use this version
uv run python --version
Installing Python versions:
# Install specific version
uv python install 3.12
# Install multiple versions
uv python install 3.11 3.12 3.13
# List available versions
uv python list --all-versions
# List installed versions
uv python list
GitHub Actions example:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up UV
uses: astral-sh/setup-uv@v6
with:
version: "0.9.5" # Pin UV version
enable-cache: true
- name: Set up Python
run: uv python install
- name: Install dependencies
run: uv sync --frozen # Use --frozen in CI
- name: Check lock file is current
run: uv lock --check
- name: Run tests
run: uv run pytest
- name: Run linting
run: uv run ruff check .
Docker optimization:
FROM python:3.12-slim
# Install UV
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Set working directory
WORKDIR /app
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies with caching
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# Copy application code
COPY . .
# Compile bytecode for faster startup
ENV UV_COMPILE_BYTECODE=1
# Run application
CMD ["uv", "run", "python", "-m", "myapp"]
Multi-stage Docker build:
# Stage 1: Build
FROM python:3.12-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-editable
# Stage 2: Runtime
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
ENV UV_COMPILE_BYTECODE=1
CMD ["python", "-m", "myapp"]
# Automated migration
uvx migrate-to-uv
# Or manual migration:
# 1. Create UV project
uv init
# 2. Import from requirements.txt
uv add -r requirements.txt
uv add --dev -r requirements-dev.txt
# 3. Commit new files
git add pyproject.toml uv.lock .python-version
git rm requirements.txt requirements-dev.txt
# Automated migration
uvx migrate-to-uv
# UV reads pyproject.toml directly
# Just start using UV commands:
uv sync # Replaces: poetry install
uv add pkg # Replaces: poetry add pkg
uv run cmd # Replaces: poetry run cmd
# Old workflow:
# python -m venv .venv
# source .venv/bin/activate # or .venv\Scripts\activate on Windows
# pip install -r requirements.txt
# New workflow:
uv init
uv add -r requirements.txt
uv run python script.py # No activation needed
Lock file out of sync:
# Error: "lock file is out of date"
uv lock # Regenerate lock file
Python version not found:
# Error: "Python 3.12 not found"
uv python install 3.12
Dependency conflicts:
# Check resolution
uv lock --verbose
# Try upgrading
uv lock --upgrade
# Check specific package
uv lock --upgrade-package problematic-package
Cache issues:
# Clean cache if corrupted
uv cache clean
# Show cache location
uv cache dir
Import resolution issues:
# Ensure environment is synced
uv sync
# Force reinstall
uv sync --reinstall
uv.lock and .python-version to version controluv sync --frozen in CI/CD pipelines.venv/ to .gitignore and .dockerignoreuv run instead of manual environment activationrequires-python range in pyproject.toml--resolution lowest for librariesUV_COMPILE_BYTECODE=1uv lock --check in CI to catch outdated lockfilesUV achieves dramatic speed improvements:
This speed enables new workflows like re-syncing environments on every command invocation without performance penalties.
For more specialized use cases, see:
UV standardizes Python development by unifying package management, environment management, Python version management, and script execution into a single fast tool. The key workflow is:
uv init to create projectsuv add to manage dependenciesuv run to execute codeuv sync --frozen in CI/CDuv.lock and .python-versionThis provides consistent, fast, reproducible Python workflows across all platforms.