uv: Python Package Management

October 20, 2025
Published in Software Engineering

Abstract

uv is a lightning-fast Python package manager written in Rust by the Astral team, designed to be a unified replacement for pip, venv, pip-tools, poetry, pyenv, and more. This comprehensive guide explores how uv transforms Python development workflows with unprecedented speed and modern tooling.

Keywords: Python, Package Management, uv, pip, Development Tools, Rust

Why uv Matters

Blazing Speed

10-100× faster installations: uv installs large libraries like Pandas or TensorFlow in seconds instead of minutes. For instance, installing JupyterLab takes uv just 2.6 seconds compared to pip's 21.4 seconds.

Millisecond virtual environment creation: Leveraging Rust's performance, uv creates virtual environments in just 4.1 milliseconds, while traditional tools require 24+ milliseconds.

Unified Toolchain

uv consolidates the functionality of multiple Python tools into one:

  • Package management: Replaces pip
  • Environment management: Replaces venv and virtualenv
  • Dependency locking: Replaces pip-tools
  • Python version management: Replaces pyenv
  • CLI tool management: Replaces pipx
  • Package building and publishing: Replaces build and twine

Modern Project Management

  • Native support for pyproject.toml (PEP 621 compliant)
  • Generates universal uv.lock files for cross-platform consistency
  • Automatic virtual environment management—no manual activation needed
  • Built-in Python version management

pip vs uv: A Comparison

Featurepipuv
Installation speedBaseline10-100× faster
Dependency lockingRequires pip-toolsNative support (uv.lock)
Virtual environmentsRequires venv (separate tool)Auto-created and managed
Config filesrequirements.txtpyproject.toml + uv.lock
Python version managementRequires pyenvBuilt-in support
MaturityMature and stableEmerging, rapidly evolving
Platform-specific depsMultiple requirements files neededSingle universal uv.lock

Installing uv

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

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

Via pip or pipx

# Option 1: Via pipx
pipx install uv

# Option 2: Via pip
pip install uv

Verify Installation and Update

# Verify installation
uv --version

# Update to latest version
uv self update

uv Fundamentals

Creating and Initializing Projects

# Create a new project
uv init my_project
cd my_project

# Initialize uv for an existing project
uv init

This creates the following structure:

  • .venv/: Virtual environment
  • pyproject.toml: Project configuration
  • uv.lock: Dependency lock file
  • .gitignore: Auto-configured
  • README.md: Project documentation
  • .python-version: Specifies Python version

Virtual Environment Management

# Create a virtual environment
uv venv

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

# Activate the virtual environment (same as standard venv)
source .venv/bin/activate  # Linux/macOS
.venv\Scripts\activate     # Windows

Dependency Management

Adding Dependencies

# Add a single package
uv add requests

# Add multiple packages
uv add numpy pandas scikit-learn

# Add a specific version
uv add 'ruff==0.3.0'

# Add with version constraints
uv add 'ruff>=0.2.0'

# Add optional dependencies
uv add 'flask[dotenv]'

# Install from GitHub
uv add 'git+https://github.com/user/repo'

# Install from local path
uv add 'package @ ./local/path'

Development Dependencies

# Add development dependencies
uv add --dev pytest black ruff mypy

# Add dependency groups
uv add --group docs sphinx

Removing Dependencies

# Remove a single package
uv remove requests

# Remove multiple packages
uv remove requests aiohttp

Upgrading Dependencies

# Upgrade a specific package
uv add --upgrade requests

# Upgrade all packages
uv lock --upgrade

Running Code

# Run a script
uv run main.py

# Run a script with arguments
uv run main.py --arg value

# Execute Python code directly
uv run python -c "import requests; print(requests.__version__)"

# Run installed tools
uv run pytest
uv run black src/

Key features of uv run:

  • Automatically creates/updates virtual environments
  • Auto-syncs dependencies
  • Ensures environment consistency

Explicit Locking and Syncing

# Explicitly generate uv.lock (usually automatic)
uv lock

# Sync dependencies to virtual environment
uv sync

# Upgrade and re-lock all dependencies
uv lock --upgrade

# Sync specific dependency groups
uv sync --group dev

Querying Dependency Information

# List installed packages
uv pip list

# Display project dependencies
uv tree

# Export as requirements.txt format
uv export -o requirements.txt

Migrating from pip to uv

Quick Migration Steps

Step 1: Initialize the project

uv init

Step 2: Import existing dependencies

# Import from existing requirements.txt
uv add -r requirements.txt

# Or preserve exact versions
uv add -r requirements.in -c requirements.txt

Step 3: Remove old virtual environment (optional)

rm -rf venv/  # Linux/macOS
rmdir /s venv # Windows

Step 4: Verify

uv run python --version
uv pip list

Command Mapping

pip commanduv commandDescription
python -m venv .venvuv venvCreate virtual environment
pip install packageuv add packageInstall package and update config
pip install -r requirements.txtuv pip install -r requirements.txtInstall from file
pip freeze > requirements.txtuv export -o requirements.txtExport dependencies
pip listuv pip listList installed packages
pip uninstall packageuv remove packageRemove package

Python Version Management

# Install specific Python versions
uv python install 3.10 3.11 3.12

# List installed Python versions
uv python list

# Pin a Python version for the project
uv python pin 3.12

# Show current Python version
uv python show

# Use specific Python in virtual environment
uv venv --python 3.11

pyproject.toml Configuration

Basic Structure

[project]
name = "my-project"
version = "0.1.0"
description = "My project description"
readme = "README.md"
requires-python = ">=3.8,<4.0"
dependencies = [
    "requests>=2.30.0",
    "numpy>=1.20.0",
]

[dependency-groups]
dev = [
    "pytest>=7.0",
    "black>=22.0",
    "mypy>=0.900",
]
docs = [
    "sphinx>=4.0",
]

[project.scripts]
# Define command-line entry points
my-tool = "module:main"

[build-system]
requires = ["setuptools>=65.0", "wheel"]
build-backend = "setuptools.build_meta"

Managing Dependency Groups

# Install all dependencies
uv sync

# Sync only specific groups
uv sync --group dev
uv sync --group docs

# Sync multiple groups
uv sync --group dev --group docs

# Exclude optional groups
uv sync --no-group dev

uv pip Interface

For special scenarios (like temporary testing or system-level tool installation), uv provides a pip-compatible interface:

# System-level installation (skip project environment)
uv pip install --system package

# Install to specific location
uv pip install --python /path/to/python package

# Compile requirements.txt (like pip-compile)
uv pip compile requirements.in -o requirements.txt

# Sync dependencies
uv pip sync requirements.txt

# Uninstall package
uv pip uninstall package

Note: uv pip commands don't update pyproject.toml or uv.lock—they're for temporary operations only. Use uv add/uv remove for project dependencies.


Building and Publishing Packages

Configure Project for Publishing

Edit pyproject.toml:

[project]
name = "my-package"
version = "0.1.0"
# ...

[project.scripts]
my-command = "module:main"

[build-system]
requires = ["setuptools>=65.0", "wheel"]
build-backend = "setuptools.build_meta"

Build Distribution Packages

# Build source distribution and wheel
uv build

# Build source distribution only (.tar.gz)
uv build --sdist

# Build wheel only (.whl)
uv build --wheel

Publish to PyPI

# Publish to PyPI (requires API token)
uv publish --token your_token_here

# Publish to TestPyPI for testing
uv publish --index testpypi --token your_token_here

Advanced uv Features

Workspaces

Manage multiple related projects:

[tool.uv.workspace]
members = ["backend", "frontend", "cli"]

Environment Variables and Configuration

# Set package index
export UV_INDEX_URL="https://pypi.mirrors.aliyun.com/simple"

# Enable verbose logging
export RUST_LOG=debug uv add package

Cache Management

# View cache information
uv cache dir

# Clear cache
uv cache clean

# Remove cache for specific packages
uv cache prune

Export Environment Information

# Export as pip-compatible requirements.txt
uv export --format requirements-txt -o requirements.txt

# Generate dependency tree
uv tree --depth 3

Real-World Example: Scientific Computing Project

Here's a practical example for a scientific computing project:

# Initialize a scientific computing project
uv init scientific-analysis
cd scientific-analysis

# Add scientific computing dependencies
uv add numpy scipy matplotlib pandas

# Add analysis tools
uv add jupyter scikit-learn

# Add development tools
uv add --dev pytest black ruff mypy

# Run Jupyter notebook
uv run jupyter notebook

# Run analysis script
uv run python analyze_data.py

# Run tests
uv run pytest tests/

Example pyproject.toml:

[project]
name = "scientific-analysis"
version = "1.0.0"
description = "Scientific data analysis workflows"
requires-python = ">=3.9"
dependencies = [
    "numpy>=1.24.0",
    "scipy>=1.10.0",
    "matplotlib>=3.7.0",
    "pandas>=2.0.0",
]

[dependency-groups]
dev = [
    "pytest>=7.0",
    "jupyter>=1.0",
    "black>=23.0",
    "ruff>=0.1.0",
]
ml = [
    "scikit-learn>=1.3.0",
    "tensorflow>=2.13.0",
]

Best Practices and Considerations

When to Use uv add vs uv pip install

ScenarioRecommended Method
Project dependency managementuv add
Development dependenciesuv add --dev
Temporary testinguv pip install
Global tool installationuv pip install --system
Specific PyTorch GPU versionsuv pip install (then manually add to project)

Version Control

  • Commit to version control: pyproject.toml and uv.lock
  • Don't commit: .venv/ directory
  • .gitignore is usually auto-configured

Multi-Member Teams

The uv.lock file ensures all developers use exactly the same dependency versions, eliminating "works on my machine" problems.

Cross-Platform Support

uv's uv.lock is universal, containing markers for all platforms. No need to create separate lock files for Windows/macOS/Linux.


Conclusion

uv represents a significant leap forward in Python package management with several key advantages:

  1. Blazing Performance: 10-100× faster than pip for installation and resolution
  2. Unified Solution: Consolidates multiple traditional tools into one
  3. Modern Standards: Native support for pyproject.toml and PEP 621
  4. Environment Consistency: Universal uv.lock files for full reproducibility
  5. Developer Efficiency: Automated virtual environment and dependency management

Whether you're working on web applications, scientific computing, machine learning, or any Python project, uv streamlines your workflow and significantly reduces the time spent on environment management. The tool is production-ready and rapidly evolving—now is the perfect time to adopt this future-facing solution for your Python projects.