npx claudepluginhub jamie-bitflight/claude_skills --plugin python-engineeringThis skill uses the workspace's default tool permissions.
uv is Astral's extremely fast Python package and project manager written in Rust, designed as a unified replacement for pip, pip-tools, pipx, poetry, pyenv, and virtualenv. It delivers 10-100x faster performance while providing modern dependency management with lockfiles and reproducible environments.
assets/docker_examples/Dockerfile.multi-stageassets/docker_examples/Dockerfile.simpleassets/github_actions/ci.ymlassets/pyproject_templates/advanced.tomlassets/pyproject_templates/basic.tomlassets/pyproject_templates/gitlab.tomlassets/script_examples/data_analysis.pyreferences/cli_reference.mdreferences/configuration.mdreferences/migration-guide.mdreferences/quick-reference.mdreferences/troubleshooting.mdscripts/sync_uv_releases.pyGenerates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
uv is Astral's extremely fast Python package and project manager written in Rust, designed as a unified replacement for pip, pip-tools, pipx, poetry, pyenv, and virtualenv. It delivers 10-100x faster performance while providing modern dependency management with lockfiles and reproducible environments.
Use this skill when:
If you're coming from another tool, here's the fast lookup:
| Old Tool | Old Command | uv Equivalent |
|---|---|---|
| pip | pip install X | uv add X |
| pip | pip install -r requirements.txt | uv add -r requirements.txt |
| pip | python -m pip install --upgrade X | uv add X (updates pyproject.toml + lockfile) |
| pip-tools | pip-compile | uv pip compile |
| pip-tools | pip-sync | uv pip sync |
| pipx | pipx run ruff | uvx ruff |
| pipx | pipx install ruff | uv tool install ruff |
| pipx | pipx upgrade ruff | uv tool upgrade ruff |
| pyenv | pyenv install 3.12 | uv python install 3.12 |
| pyenv | pyenv local 3.12 | uv python pin 3.12 |
| pyenv | pyenv global 3.12 | uv python install 3.12 --default |
| poetry | poetry add X | uv add X |
| poetry | poetry add -D X | uv add --dev X |
| poetry | poetry install | uv sync |
| poetry | poetry run X | uv run X |
| poetry | poetry shell | N/A — use uv run instead |
| virtualenv | python -m venv .venv | uv venv |
| conda | conda install X | uv add X |
For full step-by-step migration workflows, see references/migration-guide.md.
Consult ../python3-core/references/python3-standards.md when applying shared architecture, typing, testing, or CLI rules; full standards, graphs, and amendment process are documented there.
Initialize new projects:
# Standard project with recommended structure
uv init myproject
# Application project (default)
uv init myapp --app
# Library/package project (includes src/ layout)
uv init mylib --lib --build-backend hatchling
# Bare project (pyproject.toml only)
uv init --bare
Project structure created:
myproject/
├── .venv/ # Virtual environment (auto-created)
├── .python-version # Pinned Python version
├── README.md
├── main.py # Sample entry point
├── pyproject.toml # Project metadata and dependencies
└── uv.lock # Lockfile (like Cargo.lock or package-lock.json)
Add dependencies to project:
# Production dependencies
uv add requests 'flask>=2.0,<3.0' pydantic
# With automatic version bounds (stable in 0.10.0)
uv add --bounds compatible requests # Adds requests>=2.31,<3
uv add --bounds exact flask # Adds flask==3.0.0
# Development dependencies
uv add --dev pytest pytest-cov ruff mypy black
# Optional dependency groups
uv add --group docs sphinx sphinx-rtd-theme
uv add --group test pytest-asyncio hypothesis
# From various sources
uv add git+https://github.com/psf/requests@main
uv add --editable ./local-package
uv add ../sibling-package
Remove dependencies:
uv remove requests flask
uv remove --dev pytest
uv remove --group docs sphinx
Lock and sync environments:
# Update lockfile with latest compatible versions
uv lock
# Upgrade all packages
uv lock --upgrade
# Upgrade specific packages
uv lock --upgrade-package requests --upgrade-package flask
# Install all dependencies from lockfile
uv sync
# Install without dev dependencies (production)
uv sync --no-dev
# Install with optional groups
uv sync --extra docs --extra test
uv sync --extra docs,test # Comma-separated (0.9.30+)
# Sync without updating lockfile (CI mode)
uv sync --frozen
# Error if lockfile out of sync (strict CI mode)
uv sync --locked
Execute scripts and commands:
# Run Python script in project environment
uv run python script.py
# Run module (like python -m)
uv run -m pytest
uv run -m flask run --port 8000
# Run with specific Python version
uv run --python 3.11 script.py
uv run --python pypy@3.9 test.py
# Run without syncing first (use current environment state)
uv run --frozen script.py
# Run with additional temporary dependencies
uv run --with httpx --with rich script.py
# Run without project dependencies (standalone)
uv run --no-project example.py
# Run with environment variables from file
uv run --env-file .env script.py
Create portable single-file scripts with dependencies:
# Initialize script with metadata block
uv init --script example.py --python 3.12
# Add dependencies to existing script
uv add --script example.py requests rich
Example script structure:
#!/usr/bin/env -S uv --quiet run --active --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "requests>=2.31",
# "rich>=13.0",
# ]
# ///
import requests
from rich import print
response = requests.get("https://api.github.com/repos/astral-sh/uv")
print(f"Stars: {response.json()['stargazers_count']}")
Run scripts:
# Auto-creates isolated environment and runs
uv run example.py
# Run with additional dependencies
uv run --with beautifulsoup4 example.py
# Lock script for reproducibility
uv lock --script example.py # Creates example.py.lock
# Make executable and run directly
chmod +x example.py
./example.py
Best practices for scripts:
requires-python for compatibilityexclude-newer in [tool.uv] for time-based pinning (supports relative durations like "2 days ago" or "1w" since 0.9.17)One-off tool execution (ephemeral environments):
# Run tool without installing (uvx is alias)
uvx ruff check
uvx pycowsay "hello from uv"
# Run specific version
uvx ruff@0.3.0 check
uvx --from 'ruff>=0.3.0,<0.4.0' ruff check
# Run tool from different package
uvx --from httpie http GET example.com
# Run with plugin/additional dependencies
uvx --with mkdocs-material mkdocs serve
Persistent tool installation:
# Install tool globally (adds to PATH)
uv tool install ruff black mypy
# Install with version constraint
uv tool install 'httpie>0.1.0'
# Install from git
uv tool install git+https://github.com/httpie/cli
# Install with additional packages
uv tool install mkdocs --with mkdocs-material
# Upgrade tools
uv tool upgrade ruff
uv tool upgrade --all
# List installed tools
uv tool list
uv tool list --show-paths
# Uninstall tool
uv tool uninstall ruff
# Update shell configuration for tools
uv tool update-shell
Install and manage Python versions:
# Install specific Python version (auto-downloads if needed)
uv python install 3.12
uv python install 3.11 3.12 3.13 # Multiple at once
# Install and compile standard library bytecode (0.9.25+)
uv python install --compile-bytecode 3.12
# Request GIL-enabled interpreter for free-threaded Python (0.9.8+)
uv python install 3.13+gil
# List available versions
uv python list
uv python list --all-versions
# Pin Python version for project
uv python pin 3.12 # Creates .python-version
uv python pin --global 3.12 # Global pin
# Find Python executable
uv python find 3.11
# Upgrade Python installations (stable in 0.10.0)
uv python upgrade 3.11
uv python upgrade --all
uv python upgrade --compile-bytecode 3.11
# Use specific Python for command
uv run --python 3.11 script.py
uv venv --python 3.12.0
Python is automatically downloaded when needed:
~/.local/share/uv/python/ (Unix)only-managed, managed, system, only-systempypy3.10 instead of python3.10)Create virtual environments:
# Create in .venv directory (default)
uv venv
# Clear and recreate existing environment (required since 0.10.0)
uv venv --clear
# Create with specific Python version
uv venv --python 3.11
uv venv --python pypy3.9
# Create with custom path
uv venv myenv
# Create with system packages access
uv venv --system-site-packages
# Create with seed packages (pip, setuptools, wheel)
uv venv --seed
# Activate (standard Python activation)
source .venv/bin/activate # Unix
.venv\Scripts\activate # Windows
Warning (changed in 0.10.0): uv venv now refuses to overwrite an existing environment. Pass --clear (or set UV_VENV_CLEAR=1) to remove and recreate it.
Direct pip replacement commands:
# Install packages
uv pip install flask requests
uv pip install -r requirements.txt
uv pip install -e . # Editable install
# Install from git
uv pip install git+https://github.com/psf/requests
uv pip install git+https://github.com/pallets/flask@main
# Compile requirements (like pip-compile)
uv pip compile pyproject.toml -o requirements.txt
uv pip compile requirements.in -o requirements.txt
uv pip compile --upgrade-package ruff requirements.in
# Sync environment to exact requirements (like pip-sync)
uv pip sync requirements.txt
# Uninstall packages
uv pip uninstall flask requests
uv pip uninstall -r requirements.txt
# List installed packages
uv pip list
uv pip list --format json
uv pip freeze > requirements.txt
uv pip freeze --exclude setuptools --exclude pip # Exclude packages (0.9.27+)
# Show package info
uv pip show requests
# Check for conflicts
uv pip check
# Display dependency tree
uv pip tree
uv pip tree --depth 2
# Check if package is installed
uv pip freeze | grep -q '^requests=='
uv pip list --format json | jq -e '.[] | select(.name == "requests")'
uv pip show requests
Package check benchmarks (76 packages installed):
| Command | Time | Output Size |
|---|---|---|
uv pip freeze | ~8ms | ~1.5 KB |
uv pip list | ~10ms | ~2.5 KB |
uv pip list --format json | ~10ms | ~3.2 KB |
uv pip show <pkg> | ~40ms | ~0.3 KB |
uv pip show is slower because it resolves Requires and Required-by relationships.
Configure workspaces in root pyproject.toml:
[tool.uv.workspace]
members = ["packages/*", "apps/*"]
exclude = ["packages/deprecated"]
Workspace dependency references:
[project]
name = "myapp"
dependencies = ["shared-lib", "core-utils"]
[tool.uv.sources]
shared-lib = { workspace = true }
core-utils = { workspace = true }
Workspace commands:
# Build specific workspace package
uv build --package my-package
# Run in workspace package context
uv run --package my-package python script.py
# Lock workspace (single lockfile for all members)
uv lock
List and inspect workspace members:
# List all workspace members
uv workspace list
# Show workspace member paths
uv workspace list --paths
# Print workspace root directory
uv workspace dir
Exclude packages from resolution:
# In pyproject.toml
[tool.uv]
dependency-exclusions = ["unwanted-package"]
# Or via CLI
uv sync --exclude unwanted-package
Export Software Bill of Materials:
# Export dependencies as CycloneDX SBOM
uv export --format cyclonedx-json -o sbom.json
Build distributions:
# Build wheel and source distribution
uv build
# Build only wheel
uv build --wheel
# Build specific workspace package
uv build --package my-package
# Output to custom directory
uv build --out-dir dist/
Publish to PyPI:
# Publish directly with uv
uv publish
# Publish with token
uv publish --token $PYPI_TOKEN
# Publish to test PyPI
uv publish --publish-url https://test.pypi.org/legacy/
# Smoke test before publishing
uv run --isolated --no-project --with dist/*.whl python -c "import my_package"
PEP 740 attestations (0.9.12+): uv publish automatically collects and uploads attestations when available.
Build before publishing:
uv build --clear # Remove old artifacts first (0.9.6+)
uv publish --build # Build and publish in one step
Standard project configuration:
[project]
name = "myproject"
version = "1.0.0"
description = "My awesome project"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.115.2",
"pydantic>=2.5.3",
]
# Development dependencies using PEP 735 dependency groups
[dependency-groups]
dev = [
"pytest>=8.4.2",
"pytest-cov>=6.0.0",
"pytest-mock>=3.15.1",
"ruff>=0.13.3",
"pyright>=1.1.406",
"mypy>=1.18.2",
"pre-commit>=4.3.0",
]
docs = ["sphinx>=7.0", "sphinx-rtd-theme>=1.3.0"]
test = ["pytest-cov>=6.0.0", "pytest-asyncio>=0.21.0"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv]
# Core settings
managed = true
package = true
default-groups = ["dev"]
# Resolution
resolution = "highest" # or "lowest", "lowest-direct"
index-strategy = "first-index"
# Build configuration
compile-bytecode = true
no-build-isolation-package = ["flash-attn"]
# Dependency exclusions (0.9.8+)
dependency-exclusions = ["unwanted-package"]
# PyTorch accelerator backend (0.9.18+ in config)
torch-backend = "auto" # or "cu121", "rocm7.0", "cpu"
# Python management
python-preference = "managed"
python-downloads = "automatic"
# Custom package sources
[tool.uv.sources]
torch = { index = "pytorch-cu121" }
internal-lib = { workspace = true }
# Custom indexes
[[tool.uv.index]]
name = "pytorch-cu121"
url = "https://download.pytorch.org/whl/cu121"
explicit = true
Key environment variables:
# Cache and directories
export UV_CACHE_DIR="/custom/cache"
export UV_PROJECT_ENVIRONMENT=".venv"
export UV_WORKING_DIR="/path/to/project" # Preferred over UV_WORKING_DIRECTORY (0.9.14+)
# Python management
export UV_PYTHON_PREFERENCE="managed"
export UV_PYTHON_DOWNLOADS="automatic"
# Network configuration
export UV_CONCURRENT_DOWNLOADS=20
export UV_CONCURRENT_BUILDS=8
# Index authentication
export UV_INDEX_PRIVATE_USERNAME="user"
export UV_INDEX_PRIVATE_PASSWORD="pass"
# Preview features
export UV_PREVIEW=1
# Disable cache
export UV_NO_CACHE=1
# System Python
export UV_SYSTEM_PYTHON=1
# Dependency group control (0.9.8+)
export UV_NO_GROUP="docs"
export UV_NO_SOURCES=1
export UV_NO_DEFAULT_GROUPS=1
# Virtual environment (0.10.0+)
export UV_VENV_CLEAR=1 # Auto-remove existing venvs
# Build output control (0.9.15+)
export UV_HIDE_BUILD_OUTPUT=1
# Git LFS (0.9.15+)
export UV_GIT_LFS=1
# PyTorch accelerator backend
export UV_TORCH_BACKEND="cu121" # or rocm7.0, rocm7.1, cpu, auto
# SSL certificate directory (0.9.10+)
export SSL_CERT_DIR="/path/to/certs"
For complete configuration reference, see references/configuration.md.
# 1. Initialize project
uv init myproject
cd myproject
# 2. Add dependencies
uv add fastapi uvicorn sqlalchemy
# 3. Add dev dependencies
uv add --dev pytest ruff mypy
# 4. Run application
uv run python main.py
# 5. Run tests
uv run pytest
# 1. Create script with metadata
uv init --script analyze.py --python 3.11
# 2. Add dependencies
uv add --script analyze.py pandas matplotlib
# 3. Edit script content
# (add your code to analyze.py)
# 4. Lock for reproducibility
uv lock --script analyze.py
# 5. Make executable
chmod +x analyze.py
# 6. Run
./analyze.py
uv init --bare
uv add -r requirements.txt
uv add --dev -r requirements-dev.txt
uv sync
For full workflow including hybrid approach and common issues, see references/migration-guide.md.
# Option 1: Automated (recommended)
uvx migrate-to-uv
uvx migrate-to-uv --dry-run # Preview first
# Option 2: Manual
# poetry export -f requirements.txt --output requirements.txt
# uv init && uv add -r requirements.txt
For command mapping table and pyproject.toml conversion, see references/migration-guide.md.
Basic CI workflow:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.11
- name: Install dependencies
run: uv sync --frozen --all-extras
- name: Run tests
run: uv run pytest
- name: Run linters
run: |
uv run ruff check .
uv run mypy .
Publishing workflow with trusted publishing:
name: Publish
on:
push:
tags:
- v*
jobs:
publish:
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v5
- uses: astral-sh/setup-uv@v6
- run: uv python install 3.13
- run: uv build
- run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
- run: uv publish # Uses trusted publishing
Note (0.10.0): Debian Bookworm, Alpine 3.21, and Python 3.8 Docker images are no longer published. Use uv:trixie/uv:debian and uv:alpine3.22/uv:alpine instead.
FROM python:3.12-slim
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies
RUN uv sync --frozen --no-dev
# Copy application
COPY . .
# Use virtual environment
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "main.py"]
Configure uv-managed tools in .pre-commit-config.yaml:
Note: Both pre-commit and prek use the same configuration file with identical syntax.
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: custom-hook
name: Run Custom Hook
entry: uv run my-hook-script
language: system
stages: [commit]
pass_filenames: false
always_run: true
Benefits of uv run in git hooks:
Problem: error: The interpreter is externally managed
Solution: Use virtual environments instead of --system:
uv venv
source .venv/bin/activate
uv pip install package
Problem: Package fails to build from source
Common causes:
Solutions:
apt-get install python3-dev build-essentialuv add "numpy>=1.20"Problem: Dependencies changed but lockfile not updated
Solutions:
uv lock # Regenerate lockfile
uv sync --locked # Error if out of sync (CI mode)
uv sync --frozen # Don't update lockfile
Problem: Stale cache causing problems
Solutions:
uv cache size # Show cache disk usage (0.9.8+)
uv cache clean # Clean entire cache
uv cache prune # Remove unreachable entries
uv --no-cache <command> # Bypass cache temporarily
1. Forgetting --clear when recreating venvs (0.10.0+):
# Since 0.10.0, uv venv refuses to overwrite
uv venv # Errors if .venv already exists
uv venv --clear # Required to remove and recreate
2. Forgetting to sync after adding dependencies:
uv add requests # Adds to pyproject.toml and updates lockfile
uv sync # Required to actually install the package
3. Incorrect workspace glob patterns:
members = ["packages/"] (missing asterisk)members = ["packages/*"]4. Missing build-system for libraries:
Libraries and packages require a [build-system] section:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
5. Wrong file mode for TOML operations:
'r' and 'w' with tomlkit'rb' or 'wb'6. Incorrect workspace source syntax:
{ workspace = "true" } (string "true"){ workspace = true } (boolean true)7. Not using --frozen in CI:
# CI should fail if lockfile is outdated
uv sync --frozen
8. Incompatible Python version ranges in workspaces:
All workspace members must have compatible requires-python ranges. If one member requires >=3.11 and another requires >=3.12, the workspace will use >=3.12.
For more troubleshooting scenarios, see references/troubleshooting.md.
This skill includes comprehensive reference documentation:
cli_reference.md - Complete CLI commands and arguments referenceconfiguration.md - All configuration options and environment variablesmigration-guide.md - Step-by-step migration from pip, poetry, pipx, pyenv, conda — command mapping tables and common issuesquick-reference.md - Command quick reference organized by subcommand with flagsworkflows.md - Detailed workflow guides and examplestroubleshooting.md - Common issues and solutionspyproject_templates/ - Example pyproject.toml configurationsscript_examples/ - PEP 723 script templatesdocker_examples/ - Docker configuration templatesgithub_actions/ - CI/CD workflow examplesuv run instead of activating venv — it auto-syncs and is fasteruv.lock — it ensures reproducible builds across machines and CI--locked in CI/CD — fails fast if lockfile is out of sync--dev flag for test/lint/type-check dependenciesuvx for one-off tool usage — no permanent installation neededuv add not uv pip install for project dependencies — it updates pyproject.tomlsource .venv/bin/activate) — use uv runpip install alongside uv add in the same project — they don't share stateuv.lock — without it, CI and teammates get different versionsuv pip install for project deps — it bypasses pyproject.toml and lockfileuv run without --frozen or --locked in CI — let it fail explicitly if staleCurrent latest version: 0.10.2 (February 2026)
uv venv no longer auto-removes existing environments -- pass --clear or set UV_VENV_CLEAR=1default = true indexes now error (previously silently accepted)explicit indexes now error (must have a name for [tool.uv.sources] references)pypy3.10 not python3.10)uv tool run and uv tool install respect the global Python version pinuv:trixie/uv:debian and uv:alpine3.22/uv:alpineuv format upgraded to Ruff 0.15.0 (2026 style guide); pin with uv format --version 0.14.14 to opt outexclude-newer lockfile changes no longer cause full version upgrades; use --upgrade explicitlyuv python upgrade / uv python install --upgradeuv workspace list / uv workspace diruv add --bounds and add-bounds configurationextra-build-dependencies configurationuv cache size command (0.9.8)tool.uv.dependency-exclusions (0.9.8)+gil suffix for interpreter requests (0.9.8)uv export (0.9.11)uv publish (0.9.12)UV_GIT_LFS (0.9.15)exclude-newer (e.g., "2 days ago", "1w") (0.9.17)--torch-backend in [tool.uv] configuration (0.9.18)--compile-bytecode for uv python install/upgrade (0.9.25)uv pip freeze --exclude (0.9.27)--extra, --no-binary, --only-binary (0.9.30, 0.9.20)uv build --clear to remove old build artifacts (0.9.6)--project flag in uv init deprecated; use positional argument or --name (0.9.9)UV_WORKING_DIRECTORY superseded by UV_WORKING_DIR (0.9.14)