TL;DR:
- uv is an Astral-built Python package manager written in Rust that replaces pip, virtualenv, pipx, pip-tools, and pyenv with a single tool
- It installs packages 10–100x faster than pip and creates virtual environments in about 10 milliseconds
- Drop-in compatibility with pip commands means you can switch existing projects with minimal friction
The Python packaging toolchain has always been fragmented. You need pip to install packages, virtualenv or venv to isolate environments, pyenv to manage Python versions, pip-tools to pin dependencies, and pipx to install command-line tools. They each have different interfaces, different configuration files, and different mental models. uv collapses all of this into one binary.
If you’ve used Ruff — Astral’s Rust-powered linter that replaced pylint and flake8 with something dramatically faster — uv follows the same philosophy: rewrite the slow parts in Rust, unify the interface, and make the common path frictionless.
What uv Replaces
Before diving into commands, here’s the full scope of what uv covers:
| Old tool | uv equivalent |
|---|---|
pip install | uv pip install |
pip-compile (pip-tools) | uv pip compile |
python -m venv | uv venv |
pyenv install 3.12 | uv python install 3.12 |
pipx install | uv tool install |
pip-sync | uv pip sync |
You don’t have to switch everything at once. uv’s pip commands are drop-in compatible, so you can start by using uv pip install in place of pip install in your existing workflow and get the speed benefit immediately.
Installation
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or via pip, if you prefer
pip install uv
No Python version required — uv is a standalone binary that manages Python for you.
The Speed Difference
uv’s headline claim is 10–100x faster than pip. In practice:
# Creating a virtual environment
time python -m venv .venv # ~2–3 seconds
time uv venv # ~10 milliseconds
# Installing a package
time pip install numpy # 8–12 seconds (first install)
time uv pip install numpy # under 1 second (cached)
The speed comes from Rust’s performance, aggressive caching via a global package cache (dependencies are downloaded once and reused across projects), and parallel dependency resolution. Large projects with many dependencies see the most dramatic difference — installing a full data science stack goes from a coffee break to nearly instant.
Python Version Management
uv can install and manage Python versions, replacing pyenv for most use cases:
# Install a specific Python version
uv python install 3.12
# List available versions
uv python list
# Pin a project to a specific Python version
uv python pin 3.12
uv installs Python to its own managed directory and makes it available to projects without affecting your system Python. If you’re on a team where everyone needs the same Python version, committing a .python-version file (which uv reads automatically) keeps everyone in sync without pyenv.
Project Workflows
For new projects, uv has a project mode with pyproject.toml at the centre:
# Create a new project
uv init my-project
cd my-project
# Add a dependency (updates pyproject.toml and creates uv.lock)
uv add requests
# Remove a dependency
uv remove requests
# Sync your environment to match pyproject.toml
uv sync
# Run a command in the project environment
uv run python main.py
uv run pytest
The uv.lock file is deterministic and cross-platform — it records exact versions for all dependencies and their transitive dependencies. This is equivalent to pip-tools’ requirements.txt output but integrated into the project workflow.
For existing projects with a requirements.txt, migration is straightforward:
# Create a venv and install from requirements.txt
uv venv
uv pip install -r requirements.txt
Running Scripts with Inline Dependencies
One of uv’s more useful features for scripting is inline dependency metadata. You can declare dependencies at the top of a Python script and run it without manually setting up an environment:
# script.py
# /// script
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
response = requests.get("https://api.github.com/repos/astral-sh/uv")
print(response.json()["stargazers_count"])
uv run script.py
uv reads the inline metadata, creates a temporary environment with those dependencies, and runs the script. This is particularly useful for one-off automation scripts that you don’t want to pollute a project environment with.
Tool Management (replacing pipx)
For tools you want available globally (black, ruff, httpie, etc.) without polluting a project’s dependencies:
# Install a tool globally
uv tool install ruff
uv tool install httpie
# Run a tool without installing it (equivalent to npx)
uvx ruff check .
uvx pytest --version
uvx is the equivalent of npx — it runs a tool in a temporary environment without installing it permanently.
CI/CD Integration
uv fits naturally into GitHub Actions and other CI systems:
# .github/workflows/test.yml
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python
run: uv python install
- name: Install dependencies
run: uv sync --frozen
- name: Run tests
run: uv run pytest
The --frozen flag in CI prevents uv from updating the lockfile, ensuring reproducible builds. Install times in CI drop from 30–60 seconds to under 5 seconds for most projects.
Workspace Support for Monorepos
For monorepos with multiple Python packages, uv has workspace support similar to npm or Cargo workspaces:
# pyproject.toml (workspace root)
[tool.uv.workspace]
members = ["packages/*"]
Dependencies shared across packages are deduplicated in the workspace lockfile, and you can run commands across packages with uv run --package <name>.
When to Stick with pip
uv is mature and reliable for most Python development. A few edge cases where you might hit rough edges:
Legacy setuptools features. Projects using very old setup.py patterns or custom build hooks occasionally have compatibility issues. Most modern packages (using pyproject.toml and PEP 517 build backends) work without issues.
Corporate proxy environments. uv respects HTTP proxy environment variables, but some edge cases in certificate handling can require additional configuration. The uv docs have a section on this.
IDE integration. Major IDEs (VS Code, PyCharm) support uv for environment detection, but older plugins may not recognise uv-managed environments. Check your IDE’s documentation for uv-specific configuration.
For the vast majority of Python projects, uv is a straightforward drop-in that makes every install operation dramatically faster. The single-binary approach also simplifies onboarding: new team members install uv, run uv sync, and have a working environment in seconds.