| name | uv |
| description | Guide for using uv - an extremely fast Python package and project manager written in Rust. Use when installing Python, managing virtual environments, adding dependencies, running scripts, building packages, or working with pyproject.toml. Replaces pip, pip-tools, pipx, poetry, pyenv, twine, and virtualenv. |
| uv-version | >=0.5.x |
| updated | 2025-01-15T00:00:00.000Z |
uv Skill
Extremely fast Python package and project manager by Astral (Ruff creators).
Overview
uv is a single tool that replaces:
- pip/pip-tools - Package installation and dependency resolution
- virtualenv/venv - Virtual environment creation
- pyenv - Python version management
- pipx - Tool installation and execution
- poetry/pdm - Project and dependency management
- twine - Package publishing
Key Features:
- 10-100x faster than pip
- Universal lockfile (
uv.lock) for reproducible builds
- Automatic Python version management
- Built-in tool execution (
uvx)
- PEP 723 inline script dependencies
- Drop-in pip compatibility
Quick Reference
| Task | Command |
|---|
| New project | uv init |
| New library | uv init --lib |
| Add package | uv add <pkg> |
| Add dev dependency | uv add --dev <pkg> |
| Remove package | uv remove <pkg> |
| Install all deps | uv sync |
| Install (CI/prod) | uv sync --locked |
| Run command | uv run <cmd> |
| Run tool (no install) | uvx <tool> |
| Install Python | uv python install 3.12 |
| Pin Python version | uv python pin 3.12 |
| Update all deps | uv lock --upgrade |
| Update one package | uv lock --upgrade-package <pkg> |
| Show dep tree | uv tree |
| Build package | uv build |
| Publish to PyPI | uv publish |
Quick Start
Installation
curl -LsSf https://astral.sh/uv/install.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
pipx install uv
pip install uv
brew install uv
Shell Completion
echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc
echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc
echo 'uv generate-shell-completion fish | source' > ~/.config/fish/completions/uv.fish
Essential Commands
1. Starting a Project
uv init my-project
uv init --lib my-library
uv init --app my-app
uv python pin 3.12
uv python install 3.12
2. Managing Dependencies
uv add requests flask
uv add --dev pytest ruff
uv add --group test pytest
uv add --optional api flask
uv add "httpx>=0.20"
uv remove requests
uv remove --dev pytest
uv lock --upgrade
uv lock --upgrade-package requests
uv tree
uv tree --depth 2
3. Syncing Environment
uv sync
uv sync --locked
uv sync --frozen
uv sync --no-dev
uv sync --all-extras
4. Running Code
uv run python script.py
uv run pytest
uv run flask run
uv run --with pandas script.py
uvx ruff check .
uvx black --check .
uvx --from httpie http https://example.com
5. Python Version Management
uv python install
uv python install 3.12
uv python install 3.11 3.12 3.13
uv python list
uv python list --only-installed
uv python pin 3.12
uv python pin --global 3.12
uv python find
uv python find ">=3.11"
6. Virtual Environments
uv venv
uv venv my-env
uv venv --python 3.12
source .venv/bin/activate
.venv\Scripts\activate
7. Global Tools
uv tool install ruff
uv tool install "ruff==0.5.0"
uv tool install --python 3.12 mypy
uv tool list
uv tool upgrade ruff
uv tool upgrade --all
uv tool uninstall ruff
uv tool update-shell
Scripts with Inline Dependencies (PEP 723)
uv init --script example.py --python 3.12
uv add --script example.py requests rich
uv run example.py
Script format:
import requests
from rich import print
print(requests.get("https://api.example.com").json())
pip-Compatible Interface
uv pip install flask
uv pip install -r requirements.txt
uv pip install -e .
uv pip uninstall flask
uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt
uv pip freeze
Building and Publishing
uv build
uv publish
uv auth login pypi
uv auth login pypi --token
Project Structure
my-project/
├── pyproject.toml # Project definition (required)
├── uv.lock # Lock file (auto-generated)
├── .venv/ # Virtual environment (gitignored)
├── .python-version # Python version pin (optional)
└── src/
└── my_project/
└── __init__.py
pyproject.toml Example
[project]
name = "my-project"
version = "0.1.0"
description = "My awesome project"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"requests>=2.28",
"click>=8.0",
]
[project.optional-dependencies]
api = ["fastapi", "uvicorn"]
dev = ["pytest", "ruff"]
[project.scripts]
my-cli = "my_project.cli:main"
[dependency-groups]
dev = ["pytest>=8", "ruff", "mypy"]
test = ["pytest-cov"]
docs = ["sphinx", "myst-parser"]
[tool.uv]
dev-dependencies = ["pytest", "ruff"]
default-groups = ["dev"]
[tool.uv.sources]
my-lib = { git = "https://github.com/user/my-lib" }
local-pkg = { path = "./packages/local-pkg" }
torch = { index = "pytorch" }
[[tool.uv.index]]
=
=
=
Configuration
Configuration Files
Project-level (highest priority):
uv.toml - Standalone config (preferred)
pyproject.toml - Under [tool.uv] section
User-level:
~/.config/uv/uv.toml (macOS/Linux)
%APPDATA%\uv\uv.toml (Windows)
Key Environment Variables
| Variable | Purpose |
|---|
UV_CACHE_DIR | Cache directory location |
UV_PYTHON | Default Python version |
UV_INDEX_URL | Default package index |
UV_NO_CACHE | Disable caching |
UV_FROZEN | Use lockfile without updating |
UV_LOCKED | Assert lockfile unchanged |
UV_COMPILE_BYTECODE | Compile to .pyc files |
UV_LINK_MODE | Package linking mode (copy, hardlink, symlink) |
Common Workflows
New Project Setup
uv init my-project
cd my-project
uv add flask sqlalchemy
uv add --dev pytest ruff mypy
uv run flask run
uv run pytest
Existing Project (from requirements.txt)
uv init
uv add $(cat requirements.txt | grep -v "^#" | tr '\n' ' ')
uv venv
uv pip install -r requirements.txt
CI/CD Pipeline
- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- run: uv sync --locked
- run: uv run pytest
variables:
UV_CACHE_DIR: .uv-cache
UV_LINK_MODE: copy
image: ghcr.io/astral-sh/uv:latest
script:
- uv sync --locked
- uv run pytest
Docker
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY pyproject.toml uv.lock ./
# Install dependencies only (for caching)
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-install-project
# Copy source and install project
COPY . .
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "-m", "my_app"]
direnv Integration
if has uv; then
VIRTUAL_ENV="$(pwd)/.venv"
if [[ ! -d "$VIRTUAL_ENV" ]]; then
uv venv
fi
PATH_add "$VIRTUAL_ENV/bin"
export VIRTUAL_ENV
fi
Migration Guide
From pip + requirements.txt
uv init
cat requirements.txt | grep -v "^#" | grep -v "^-e" | \
cut -d'=' -f1 | cut -d'>' -f1 | xargs uv add
uv venv
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
Key differences:
uv.lock replaces requirements.txt for locking
pyproject.toml replaces requirements.in for declaring dependencies
- Use
uv run instead of activating virtualenv
From Poetry
cd existing-poetry-project
uv sync
Migrate pyproject.toml (optional but recommended):
[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.28"
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
[project]
requires-python = ">=3.11"
dependencies = ["requests>=2.28"]
[dependency-groups]
dev = ["pytest>=8.0"]
Command equivalents:
| Poetry | uv |
|---|
poetry install | uv sync |
poetry add requests | uv add requests |
poetry add -D pytest | uv add --dev pytest |
poetry remove requests | uv remove requests |
poetry run pytest | uv run pytest |
poetry lock | uv lock |
poetry build | uv build |
poetry publish | uv publish |
From Pipenv
pipenv requirements > requirements.txt
pipenv requirements --dev > requirements-dev.txt
uv init
cat requirements.txt | grep -v "^#" | xargs uv add
cat requirements-dev.txt | grep -v "^#" | xargs uv add --dev
rm Pipfile Pipfile.lock
Command equivalents:
| Pipenv | uv |
|---|
pipenv install | uv sync |
pipenv install requests | uv add requests |
pipenv install --dev pytest | uv add --dev pytest |
pipenv run pytest | uv run pytest |
pipenv lock | uv lock |
pipenv shell | source .venv/bin/activate (or use uv run) |
From pyenv (Python version management only)
uv python install 3.11 3.12 3.13
uv python pin 3.12
uv python list --only-installed
Note: You can use pyenv and uv together - uv will detect pyenv-installed Pythons.
From conda
uv does not replace conda for:
- Non-Python dependencies (C libraries, CUDA, etc.)
- Conda-specific packages not on PyPI
For pure Python projects:
conda list --export > conda-packages.txt
grep -v "^#" conda-packages.txt | grep -v "conda" | cut -d'=' -f1 > packages.txt
uv init
uv add $(cat packages.txt | tr '\n' ' ')
Hybrid approach: Use conda for system dependencies, uv for Python packages:
conda create -n myenv python=3.12 cudatoolkit
conda activate myenv
export UV_SYSTEM_PYTHON=1
uv pip install -r requirements.txt
Common Pitfalls
1. Forgetting --locked in CI/Production
uv sync
uv sync --locked
2. Mixing uv and pip Commands
pip install some-package
source .venv/bin/activate && pip install another-package
uv add some-package
uv pip install some-package
3. Not Committing uv.lock
The uv.lock file must be committed to version control for
reproducible builds. Without it, environments may resolve differently.
# .gitignore - DON'T ignore uv.lock
.venv/
__pycache__/
# uv.lock <-- DO NOT ADD THIS LINE
4. Running Commands Outside Project Environment
python script.py
pytest
uv run python script.py
uv run pytest
5. Editing uv.lock Manually
Never edit uv.lock by hand. It's auto-generated and managed by uv.
uv lock --upgrade-package requests
uv lock --upgrade
rm uv.lock && uv lock
6. Using --frozen When You Mean --locked
uv sync --frozen
uv sync --locked
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|
No pyproject.toml | Wrong directory | cd to root or uv init |
| Package not found | Wrong index/typo | Check name, try --index |
| Lockfile outdated | pyproject changed | Run uv lock |
Resolver conflict | Version conflicts | Try uv lock --upgrade |
| Python mismatch | Not installed | uv python install 3.12 |
| Build failures | Missing deps | Try --no-build-isolation |
| Hash mismatch | Corrupted cache | uv cache clean |
| Slow first run | Cold cache | Normal, uses cache after |
Debug Commands
uv python find
uv pip list
uv sync -v
uv sync -vv
uv lock --check
uv cache clean
uv cache prune --ci
References
references/cli-commands.md - Complete CLI reference
references/project-management.md - Project and dependency management
references/python-versions.md - Python version management
references/integrations.md - Docker, CI/CD, and tool integrations
External Links
Absorbed sub-skill (post-consolidation)
This skill now subsumes the former python-project skill (project scaffolding). Original content preserved under:
| Subject | Path |
|---|
| Python project scaffolding (Flask/pytest patterns, project structure) | References/python-project.md |
| Project references | References/python-project-references/ |
| Project scripts | References/python-project-scripts/ |
Gotchas
uv pip install -e . works but doesn't write the editable install to uv.lock — the lockfile is wrong on next uv sync. Use uv add --editable instead.
uv sync --frozen fails if dependencies upgraded outside the lock — won't auto-update; emit a clear error message but blocks CI until you uv lock --upgrade-package <name>.
uv venv creates .venv in CWD — missing --directory after cd puts the venv in the wrong place. Pin with UV_PROJECT_ENVIRONMENT env var or absolute paths in scripts.
uv tool install and uv pip install go to DIFFERENT environments — uv tools are isolated per-tool; pip-installed packages aren't visible to uv-installed tools.
- Pin via
==X.Y.Z in pyproject.toml doesn't lock; only uv.lock does — dependencies = ["foo==1.2.3"] allows uv to pick any compatible 1.2.3, including yanked versions.