Python uv Package Manager 2026: The 10x Faster pip Replacement Guide

编程语言

The Dark Ages of Python Dependency Management

Every Python developer has experienced these pains:

  • pip installs at a snail's pace: A Django project pip install can take minutes, with dependency resolution stuck at the Collecting stage driving you crazy
  • poetry configuration is incomprehensible: pyproject.toml dependency groups, extras, and source configurations are headache-inducing, and lock file conflicts are commonplace
  • venv manual management is tedious: python -m venv .venv, source .venv/bin/activate, deactivate... repeating this workflow for every project
  • Python version switching is chaotic: pyenv, conda, and system Python fighting each other, which python never pointing where you expect
  • Dependency locking is unreliable: requirements.txt has no lock file, pip freeze > requirements.txt includes transitive dependencies, making environments non-reproducible

In 2024, the Astral team (creators of ruff) released uv -- a Python package manager written in Rust, 10-100x faster than pip. By 2026, uv has become the most watched package management tool in the Python ecosystem, supporting project management, virtual environments, Python version management, Monorepo workspaces, and more.

This article will guide you through mastering uv via 5 practical patterns, starting from core concepts.


Core Concepts Reference

Concept Description Command
Project Management Initialize projects, manage dependency declarations uv init, uv add, uv remove
Virtual Environment Automatically create and manage .venv uv venv, uv sync
Python Version Management Install and switch Python interpreters uv python install, uv python pin
Dependency Locking Generate reproducible lock files uv lock (auto-generates uv.lock)
Dependency Resolution High-performance dependency tree resolution Built-in Rust resolver, 10-100x speedup
Workspace Monorepo multi-package management uv workspace
Tool Running Temporarily install and run CLI tools uv tool run, uvx
Script Execution Inline dependency declarations and run scripts uv run script.py
Cache Management Global package cache, avoid redundant downloads uv cache
Export Dependencies Export to requirements.txt format uv export

Five Core Challenges

Challenge 1: Dependency Resolution Speed

pip uses a backtracking resolution algorithm; complex dependency graphs can take minutes or fail entirely. uv employs a high-performance resolver based on a SAT solver, typically completing resolution in milliseconds.

Challenge 2: Environment Consistency

requirements.txt lacks complete dependency locking information; installations on different machines may yield different results. uv's uv.lock lock file records the full dependency tree hashes, ensuring exact reproducibility in any environment.

Challenge 3: Python Version Fragmentation

Different projects require different Python versions; the pyenv + venv combination is cumbersome to configure. uv has built-in Python version management -- one command to install and switch, no additional tools needed.

Challenge 4: Monorepo Dependency Sharing

Multiple sub-packages have internal dependency relationships; traditional approaches require manual publishing to private PyPI or using pip install -e. uv workspace natively supports Monorepo with automatic linking between sub-packages.

Challenge 5: CI/CD Cache Efficiency

pip re-downloads dependencies on every CI run; even with caching, cache misses are frequent. uv's global cache + content-addressable mechanism achieves near-100% CI cache hit rates.


Pattern 1: uv Installation and Project Initialization

Installing uv

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Install via pip (not recommended, fallback only)
pip install uv

# Using Homebrew
brew install uv

# Verify installation
uv --version
# uv 0.7.12 (2026 latest stable release)

Project Initialization

# Create a new project
uv init my-project
cd my-project

# Project structure
# my-project/
# ├── .python-version    # Python version pin
# ├── pyproject.toml     # Project config and dependency declarations
# ├── uv.lock            # Dependency lock file (auto-generated)
# ├── hello.py           # Sample entry file
# └── .venv/             # Virtual environment (auto-created)

Dependency Management

# Add dependencies
uv add fastapi
uv add "sqlalchemy>=2.0"
uv add --dev pytest
uv add --dev ruff

# Add optional dependency group
uv add --optional ml torch

# Remove dependencies
uv remove pytest

# Sync dependencies (install all declared in pyproject.toml)
uv sync

# Sync production dependencies only (exclude dev)
uv sync --no-dev

# Sync specific group
uv sync --group ml

pyproject.toml Structure

[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115.0",
    "sqlalchemy>=2.0",
]

[project.optional-dependencies]
ml = [
    "torch>=2.5",
    "transformers>=4.45",
]

[tool.uv]
dev-dependencies = [
    "pytest>=8.0",
    "ruff>=0.8",
]

[tool.uv.sources]
my-private-pkg = { git = "https://github.com/myorg/my-private-pkg.git", tag = "v1.0.0" }

Running Projects

# Run a script in the virtual environment
uv run python hello.py

# Run a module
uv run python -m my_project.main

# Run a script with inline dependency declaration
uv run --with requests python fetch_data.py

Pattern 2: Virtual Environment and Python Version Management

Virtual Environment Management

# Create a virtual environment (default .venv directory)
uv venv

# Create with specific Python version
uv venv --python 3.12

# Specify virtual environment path
uv venv /path/to/.venv

# Activate virtual environment
# macOS / Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate

# uv sync automatically creates virtual environment
uv sync

Python Version Management

# List available Python versions
uv python list

# Install specific Python version
uv python install 3.12
uv python install 3.13

# Install specific implementations
uv python install pypy3.10
uv python install graalpy3.11

# Pin project Python version (writes to .python-version)
uv python pin 3.12

# List installed versions
uv python list --only-installed

# Find Python interpreter path
uv python find 3.12

# Temporarily use a specific version
uv run --python 3.13 python --version

.python-version File

3.12

This file is automatically read by uv, ensuring team members use a consistent Python version. Combined with uv sync, new team members can set up a complete environment with a single command after cloning.

Multi-Version Parallel Scenarios

# Project A uses Python 3.12
cd project-a
uv python pin 3.12
uv sync

# Project B uses Python 3.13
cd project-b
uv python pin 3.13
uv sync

# Projects don't interfere; no pyenv switching needed

Pattern 3: Migration from pip/requirements.txt and poetry/pyproject.toml

Migrating from pip + requirements.txt

# Option 1: Initialize in an existing project
cd existing-project
uv init
# uv detects existing requirements.txt and auto-imports

# Option 2: Manually import dependencies
uv add $(cat requirements.txt | grep -v "^#" | grep -v "^$" | tr "\n" " ")

# Option 3: Use uv pip compatibility mode (transition period)
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt

# Export back to requirements.txt format
uv export > requirements.txt
uv export --no-dev > requirements-prod.txt

Migrating from poetry

# uv reads poetry's pyproject.toml directly
cd poetry-project
uv init
# uv auto-detects [tool.poetry.dependencies] and migrates

# Manual migration steps
# 1. Backup poetry.lock
cp poetry.lock poetry.lock.bak

# 2. Convert poetry dependency format to PEP 621 format
# Poetry format:
#   [tool.poetry.dependencies]
#   fastapi = "^0.115.0"
# PEP 621 format:
#   [project]
#   dependencies = ["fastapi>=0.115.0"]

# 3. Generate uv.lock
uv lock

# 4. Sync dependencies
uv sync

Poetry to uv pyproject.toml Conversion Script

import tomllib
import tomli_w
from pathlib import Path


def migrate_poetry_to_uv(pyproject_path: str = "pyproject.toml"):
    ""Convert poetry-format pyproject.toml to uv-compatible format""
    path = Path(pyproject_path)
    data = tomllib.loads(path.read_text(encoding="utf-8"))

    poetry_deps = data.get("TOOL", {}).get("poetry", {}).get("dependencies", {})
    poetry_dev_deps = (
        data.get("TOOL", {})
        .get("poetry", {})
        .get("group", {})
        .get("dev", {})
        .get("dependencies", {})
    )

    def convert_version(version_spec: str) -> str:
        if isinstance(version_spec, dict):
            return version_spec.get("version", "*")
        if version_spec.startswith("^"):
            base = version_spec[1:]
            parts = base.split(".")
            upper = f"{int(parts[0]) + 1}.0.0"
            return f">={base},<{upper}"
        if version_spec.startswith("~"):
            base = version_spec[1:]
            parts = base.split(".")
            upper = f"{parts[0]}.{int(parts[1]) + 1}.0"
            return f">={base},<{upper}"
        return version_spec

    dependencies = []
    for name, version in poetry_deps.items():
        if name == "python":
            data.setdefault("project", {})["requires-python"] = f">={version}"
            continue
        dep = convert_version(version)
        dependencies.append(f"{name}{dep}" if dep != "*" else name)

    data.setdefault("project", {})["dependencies"] = dependencies

    dev_dependencies = []
    for name, version in poetry_dev_deps.items():
        dep = convert_version(version)
        dev_dependencies.append(f"{name}{dep}" if dep != "*" else name)

    if dev_dependencies:
        data.setdefault("TOOL", {}).setdefault("uv", {})[
            "dev-dependencies"
        ] = dev_dependencies

    if "poetry" in data.get("TOOL", {}):
        del data["TOOL"]["poetry"]

    path.write_text(tomli_w.dumps(data), encoding="utf-8")
    print(f"Migration complete: {dependencies=}, {dev_dependencies=}")


if __name__ == "__main__":
    migrate_poetry_to_uv()

Migrating from pipenv

# Export Pipfile dependencies to requirements.txt
pipenv requirements > requirements.txt

# Initialize with uv and import
uv init
uv add $(cat requirements.txt | tr "\n" " ")
uv sync

Pattern 4: Monorepo and Workspace Management

Workspace Initialization

# Create Monorepo root directory
mkdir my-monorepo && cd my-monorepo
uv init --workspace

# Create sub-packages
uv init --package libs/core
uv init --package libs/api
uv init --package apps/web

# Project structure
# my-monorepo/
# ├── pyproject.toml          # Workspace root config
# ├── uv.lock                 # Global lock file (unified management)
# ├── libs/
# │   ├── core/
# │   │   ├── pyproject.toml
# │   │   └── src/core/
# │   └── api/
# │       ├── pyproject.toml
# │       └── src/api/
# └── apps/
#     └── web/
#         ├── pyproject.toml
#         └── src/web/

Root pyproject.toml Configuration

[tool.uv.workspace]
members = [
    "libs/core",
    "libs/api",
    "apps/web",
]

[tool.uv.sources]
core = { workspace = true }
api = { workspace = true }

Sub-package pyproject.toml

# libs/core/pyproject.toml
[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "pydantic>=2.9",
]

# libs/api/pyproject.toml
[project]
name = "api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "core",
    "fastapi>=0.115.0",
]

# apps/web/pyproject.toml
[project]
name = "web"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "core",
    "api",
    "uvicorn>=0.32.0",
]

Workspace Operations

# Sync entire workspace
uv sync

# Sync specific sub-package only
uv sync --package api

# Run command in specific sub-package
uv run --package api python -m api.main

# Add dependency to specific sub-package
uv add --package api httpx

# Build specific sub-package
uv build --package core

# Publish specific sub-package
uv publish --package core

Workspace Dependency Graph Verification

# View dependency tree
uv tree

# Check dependency conflicts
uv lock --check

# Update specific dependency
uv lock --upgrade-package fastapi

Pattern 5: CI/CD Integration and Docker Optimization

GitHub Actions Integration

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4
        with:
          version: "latest"
          enable-cache: true
          cache-dependency-glob: "uv.lock"

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync --frozen

      - name: Run linter
        run: uv run ruff check .

      - name: Run tests
        run: uv run pytest --cov=src --cov-report=xml

      - name: Upload coverage
        uses: codecov/codecov-action@v4

GitLab CI Integration

# .gitlab-ci.yml
stages:
  - test
  - build

test:
  stage: test
  image: python:3.12-slim
  before_script:
    - pip install uv
    - uv python install 3.12
    - uv sync --frozen
  script:
    - uv run ruff check .
    - uv run pytest --cov=src
  cache:
    key:
      files:
        - uv.lock
    paths:
      - .venv/
      - ~/.cache/uv/

build:
  stage: build
  image: python:3.12-slim
  before_script:
    - pip install uv
  script:
    - uv build
  artifacts:
    paths:
      - dist/

Docker Multi-Stage Build Optimization

# Dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv

FROM python:3.12-slim AS deps
COPY --from=uv /uv /usr/local/bin/uv

WORKDIR /app

COPY pyproject.toml uv.lock ./

RUN uv sync --frozen --no-install-project --no-dev

FROM python:3.12-slim AS runtime

WORKDIR /app

COPY --from=deps /app/.venv /app/.venv

COPY . .

ENV PATH="/app/.venv/bin:$PATH"
ENV VIRTUAL_ENV="/app/.venv"

CMD ["python", "-m", "my_project.main"]

Docker Compose Development Environment

# docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - uv-cache:/root/.cache/uv
    environment:
      - PYTHONUNBUFFERED=1
    command: uv run uvicorn my_project.main:app --host 0.0.0.0 --reload

volumes:
  uv-cache:

CI Cache Optimization Tips

# Use --frozen to ensure lock file is not modified (required in CI)
uv sync --frozen

# Use --no-dev to reduce install size
uv sync --frozen --no-dev

# Offline install (when dependencies are cached)
uv sync --frozen --offline

Common Pitfalls Guide

Pitfall 1: Mixing pip and uv

❌ Using pip install in a uv-managed project, bypassing uv's dependency management

✅ Always use uv add to add dependencies and uv sync to sync environments. For temporary installs, use uv pip install (compatibility mode)

Pitfall 2: Ignoring uv.lock in Version Control

❌ Adding uv.lock to .gitignore, causing inconsistent dependency versions across team members

✅ Commit uv.lock to version control, ensuring all environments use the same dependency versions. Use --frozen in CI to prevent accidental updates

Pitfall 3: Forgetting to Pin Python Version

❌ Not setting .python-version, causing compatibility issues when developers use different Python versions

✅ Use uv python pin 3.12 to pin the version, and commit .python-version to the repository

Pitfall 4: Global Install Pollution

❌ Installing numerous global tools with uv tool install, making version conflicts hard to troubleshoot

✅ Use uv run --with for project-level temporary installs; only install frequently-used global tools (like ruff, black)

Pitfall 5: Not Leveraging Docker Cache Layers

❌ COPY all source code before uv sync, re-installing dependencies on every code change

✅ COPY pyproject.toml + uv.lock first, then uv sync, then COPY source code. Leverage Docker cache layers to avoid redundant installs


Error Troubleshooting Table

Error Possible Cause Solution
error: No virtual environment found Virtual environment not created Run uv sync or uv venv to auto-create
error: Failed to download package Network issue or PyPI unreachable Configure mirror: uv pip config set global.index-url https://pypi.org/simple
error: Python 3.12 not found Python version not installed Run uv python install 3.12
error: Lockfile is out of date pyproject.toml updated without re-locking Run uv lock to update the lock file
error: Resolution failed Dependency version conflict Check version constraints in pyproject.toml, use uv tree to view dependency tree
error: Package not found in workspace Workspace member misconfigured Check [tool.uv.workspace] members paths
uv sync is slow Cache miss or network latency Check cache directory permissions, configure mirror, use --offline mode
error: Hash mismatch Package tampered or cache corrupted Run uv cache clean and retry
error: Cannot activate venv Virtual environment corrupted Delete .venv directory and re-run uv sync
error: Unsupported Python version Python version doesn't meet requires-python Run uv python install to install a compatible version

Advanced Optimization Tips

1. Mirror Acceleration

# Configure PyPI mirror
uv pip config set global.index-url https://pypi.org/simple

# Or configure in pyproject.toml
# [tool.uv]
# index-url = "https://pypi.org/simple"

# Multi-source configuration (private PyPI + public)
# [tool.uv]
# extra-index-url = ["https://pypi.mycompany.com/simple/"]

2. Cache Management

# View cache info
uv cache dir

uv cache list

# Clear cache
uv cache clean

# Clear cache for specific package
uv cache clean numpy

# View cache size
du -sh $(uv cache dir)

3. Offline Environment Deployment

# Export dependencies to vendor directory
uv export --no-dev > requirements.txt
uv pip download -r requirements.txt -d vendor/

# Offline install
uv pip install --no-index --find-links vendor/ -r requirements.txt

4. Script Inline Dependencies

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests>=2.32",
#     "rich>=13.0",
# ]
# ///

import requests
from rich import print

response = requests.get("https://httpbin.org/json")
print(response.json())
# Run directly; uv auto-installs dependencies
uv run script.py

5. Dependency Security Audit

# Check known vulnerabilities
uv audit

Tool Comparison

Dimension uv pip poetry pdm conda
Resolution Speed Extremely fast (Rust) Slow (backtracking) Medium Fast Slow
Virtual Env Management Built-in Requires venv Built-in Built-in Built-in
Python Version Mgmt Built-in Requires pyenv Requires pyenv Built-in Built-in
Lock File uv.lock None poetry.lock pdm.lock None
Monorepo Support Native workspace No No Limited No
CI Cache Friendly Excellent Fair Good Good Poor
Configuration Complexity Low Low High Medium High
Ecosystem Maturity Rapidly growing Most mature Mature Growing Mature
Learning Curve Gentle Gentle Steep Medium Steep
Package Count Full PyPI Full PyPI Full PyPI Full PyPI Anaconda + PyPI
Cross-language Support Python only Python only Python only Python only Multi-language (C/C++/R)
Recommendation ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐

Selection Recommendations:

  • New projects → uv (full-stack capability, blazing speed)
  • Existing poetry projects → Gradually migrate to uv (compatible with poetry config)
  • Data science/ML projects → uv + conda complement (uv for pure Python, conda for C/C++ deps)
  • Simple scripts/one-off tasks → uv run (no project initialization needed)

In Python project development, these ToolsKu tools can help you:

  • JSON Formatter — Format API responses and config files, debug JSON data in pyproject.toml
  • Hash Calculator — Compute dependency package hashes, verify download integrity
  • cURL to Code — Convert API requests to Python code in one click, quickly build HTTP clients

Python dependency management has evolved from easy_install to pip, from requirements.txt to poetry.lock. uv is not simply a replacement -- it perfectly combines Rust's high performance with Python's ease of use, transforming dependency management from "a pain you have to endure" into "an experience that's nearly invisible". In 2026, uv is ready to be your default choice.

Try these browser-local tools — no sign-up required →

#Python包管理#uv工具#pip替代#Python依赖管理#2026#编程语言