uv-python-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.
When to Use This Skill
Use this skill when:
- •Creating new Python projects
- •Managing dependencies and lockfiles
- •Setting up virtual environments
- •Installing or switching Python versions
- •Building or publishing packages
- •Optimizing CI/CD pipelines
- •Migrating from pip, poetry, or other tools
- •Creating portable Python scripts
- •Working with Docker containers
Core Principles
- •Project-first workflow: Use
uv initanduv addinstead of manual configuration - •Lock file discipline: Always commit
uv.lockfor reproducibility - •Universal execution: Use
uv runinstead of manual environment activation - •Version pinning: Use
.python-versionfor team consistency - •Fast by default: Leverage caching and parallel operations (8-100x faster than pip)
Quick Start
Installing UV
# 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
Creating a New Project
# 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
Essential Commands Reference
Project Lifecycle
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
Python Version Management
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
Virtual Environments
uv venv # Create virtual environment (.venv/) uv venv --python 3.12 # Create with specific Python version uv venv my-env # Create with custom name
Lock File Management
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
Tool Management (replaces pipx)
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
Maintenance
uv cache clean # Clean cache uv cache dir # Show cache location uv self update # Update UV itself
Project Structure Best Practices
Standard Layout
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
pyproject.toml Structure
[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"]
Key Workflows
Dependency Management
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
Running Code
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:
- •Auto-syncs environment before running
- •Works cross-platform without activation scripts
- •Ensures reproducibility
- •Handles environment discovery automatically
Inline Script Dependencies (PEP 723)
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)
Python Version Management
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
CI/CD Integration
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"]
Migration from Existing Tools
From pip/pip-tools
# 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
From Poetry
# 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
From virtualenv/venv
# 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
Troubleshooting
Common Issues
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
Best Practices Checklist
- •✅ Always commit
uv.lockand.python-versionto version control - •✅ Use
uv sync --frozenin CI/CD pipelines - •✅ Add
.venv/to.gitignoreand.dockerignore - •✅ Pin UV version in CI for consistency
- •✅ Use
uv runinstead of manual environment activation - •✅ Specify
requires-pythonrange inpyproject.toml - •✅ Use dependency groups for dev tools, not optional-dependencies
- •✅ Test with
--resolution lowestfor libraries - •✅ Enable bytecode compilation in Docker:
UV_COMPILE_BYTECODE=1 - •✅ Use cache mounts in Docker for faster builds
- •✅ Run
uv lock --checkin CI to catch outdated lockfiles - •✅ Leverage inline script dependencies (PEP 723) for portable tools
- •✅ Document UV setup in README for team onboarding
Performance Impact
UV achieves dramatic speed improvements:
- •8-10x faster than pip without caching
- •80-115x faster with warm cache
- •Virtual environment creation: 100ms vs 8 seconds (python -m venv)
- •Complex dependency resolution: seconds vs minutes
- •CI/CD impact: 30-65% faster builds
This speed enables new workflows like re-syncing environments on every command invocation without performance penalties.
Advanced Topics
For more specialized use cases, see:
- •WORKSPACE.md - Monorepo and multi-project setups
- •PUBLISHING.md - Building and publishing packages
- •SCRIPTS.md - Advanced script management patterns
Key Differences from Other Tools
vs pip
- •Speed: 8-100x faster
- •Lock files: Built-in universal lockfiles
- •Python management: Can install Python versions
- •Unified: Replaces pip + pip-tools + virtualenv
vs Poetry
- •Speed: Significantly faster resolution and installation
- •Lock files: Universal (cross-platform in one file)
- •Simpler: Less configuration required
- •Compatible: Reads Poetry's pyproject.toml
vs Conda
- •Scope: Python-only (doesn't handle system dependencies)
- •Speed: Much faster for Python packages
- •Compatibility: Standard PyPI ecosystem
- •Not a replacement: Use Conda when you need non-Python dependencies
Support and Resources
- •Documentation: https://docs.astral.sh/uv/
- •GitHub: https://github.com/astral-sh/uv
- •Discord: Join Astral's community
- •Changelog: https://github.com/astral-sh/uv/releases
Summary
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 initto create projects - •
uv addto manage dependencies - •
uv runto execute code - •
uv sync --frozenin CI/CD - •Commit
uv.lockand.python-version
This provides consistent, fast, reproducible Python workflows across all platforms.