uv: A Modern, High-Performance Python Package Manager
Listen to this article
Summary
uv is a Rust-based, all-in-one Python package and project manager that unifies the roles of pip, virtualenv, pip-tools, pipx, and Python version managers under a single interface.
It offers significant performance improvements, with benchmarks reporting up to 10× faster installs than pip without cache and up to 100× faster with a warm global cache.
uv generates a lockfile for reproducible installs, supports dev dependency separation in pyproject.toml, and provides commands like uv init, uv add, uv sync, and uv run for project workflows.
pip may still be preferable for existing production systems, minimal Docker images, or maximum compatibility with older Python workflows.
Package management in Python has long been dominated by tools like pip and virtualenv, often supported by auxiliary utilities for dependency locking and environment management. With growing project complexity and demands for faster CI/CD workflows, the Python ecosystem is evolving.
One of the newest entrants is uv, a Rust-based, all-in-one package and project manager designed for speed and unification of traditional tools.
This article explains what UV is, how it differs from and improves on pip, and provides a step-by-step guide to adopting it in real Python projects. You’ll also find a sample pyproject.toml with commentary on dev dependencies for common workflows like testing and quality checks.
Why UV exists
Python tooling historically has used a mix of utilities:
pip for installing packages
virtualenv / venv for isolated environments
pip-tools for compile/sync workflows
pipx for global CLI tool installation
pyenv or similar for Python version management
Each utility addresses a subset of project setup and dependency management, but also introduces friction in configuration and performance. UV aims to unify these responsibilities under a single interface, with performance and usability improvements out of the box.
At its core, UV is:
A drop-in replacement for pip (fully compatible with PyPI and requirements.txt)
A virtual environment manager
A dependency resolver and lockfile generator
A project scaffolding tool
A Python version installer (optional)
UV vs. pip: What’s different
Performance
Because uv is written in Rust and handles multiple downloads and resolutions in parallel while using a global cache, installation workflows are significantly faster than standard pip operations.
Benchmarks report up to 10× faster installations compared to pip even without cache, and up to 100× faster when the global cache is warm, which is the most common scenario in day-to-day development, since dependencies rarely change between runs.
Unified toolchain
With UV, you don’t need to coordinate multiple CLI tools for environment setup, dependencies, and Python version control. A single interface simplifies both local development and CI/CD scripts.
Lockfiles and reproducibility
Unlike relying solely on a plain requirements.txt, uv produces a lockfile that records precise versions and metadata. This ensures consistent installs across machines and builds.
Installation and getting started
Installing uv
You can install UV using one of the following methods. Standalone installers are recommended for full functionality.
pip install uv
# or
pipx install uvCode language:PHP(php)
Once installed, confirm the version:
uv --version
At this point, you can start using UV in your Python projects.
Step-by-step: Using UV in a Python project
1. Initialize a project
Create a new project and initialize it with uv. This sets up a directory with basic config:
mkdir myproject && cd myproject
uv init
This creates:
pyproject.toml – project configuration
Lockfile – dependency snapshot
Virtual environment defaults
2. Adding dependencies
To install runtime dependencies:
UV add requests Flask
For development dependencies (e.g., for testing):
uv add --dev pytest pytest-cov
uv separates dev dependencies under the dev section in pyproject.toml, similar to other modern package managers.
3. Syncing dependencies
To install packages based on your lockfile:
uv sync
This ensures reproducible installs every time, unlike ad-hoc installs with pip install.
4. Running code
To run Python with the managed environment:
uvrunpythonmain.pyCode language:CSS(css)
You can also run tools directly:
uv run pytest
Example pyproject.toml
Below is an annotated sample configuration:
[project]
name = "myproject"
version = "0.1.0"
description = "Example project using uv"
authors = ["Your Name <you@example.com>"]
dependencies = [
"requests>=2.28.0",
"flask>=2.2.0",
]
[dependency-groups]
dev = [
"pytest>=7.0.0",
"pytest-cov",
"ruff",
"black",
]
[tool.uv]
python = ">=3.10"Code language:JavaScript(javascript)
Explanation:
[project]: Standard metadata used for packaging and project identity.
dependencies: Runtime packages installed via uv add ….
optional-dependencies.dev: Development dependencies for testing and code quality (pytest, ruff, black). These are only installed in development contexts.
[tool.uv]: uv-specific configuration, such as Python version constraints and lockfile location.
This structure ensures a clean separation between primary and dev dependencies while maintaining reproducibility via the lockfile.
Integrating testing and quality workflows
Once dependencies are installed, you can integrate standard workflows:
Linting:
uv run ruff .
Formatting:
uv run black .
Running tests:
uv run pytest
These commands run within the uv-managed environment, eliminating the need for separate virtualenv activation steps.
Project scoping: Easier development scripting and tooling integration.
When pip still makes sense
Existing production systems that assume pip as part of the system Python.
Docker images where only pip is installed by default, and you need a minimal footprint.
Maximum compatibility with older Python workflows.
In many modern development contexts, UV can streamline workflows without sacrificing compatibility with PyPI and requirements formats.
Summary
UV is an emerging Python package and project manager that unifies multiple tools into a single interface while delivering performance improvements and simplified workflows. It is both a drop-in replacement for pip workflows and a more capable project manager with lockfiles, environment control, and dev dependencies built in.
By adopting UV, teams can reduce tooling complexity and speed up local development and CI/CD pipelines. The integration with a pyproject.toml-centric workflow also aligns with modern Python packaging standards.
share this article
FAQ
What is UV?
UV is a Rust-based, all-in-one package and project manager for Python designed for speed and unification of traditional tools. At its core, it is a drop-in replacement for pip (fully compatible with PyPI and requirements.txt), a virtual environment manager, a dependency resolver and lockfile generator, a project scaffolding tool, and an optional Python version installer.
How does UV differ from pip in performance?
Because UV is written in Rust and handles multiple downloads and resolutions in parallel while using a global cache, installation workflows are significantly faster than standard pip operations. Benchmarks report up to 10× faster installations compared to pip even without cache, and up to 100× faster when the global cache is warm.
How do you install UV and verify the installation?
You can install UV using standalone installers (recommended for full functionality) on macOS/Linux or Windows via PowerShell (powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"), or alternatively via pip (pip install uv) or pipx (pipx install uv). After installation, confirm the version with uv --version.
What are the basic steps to use UV in a Python project?
First, initialize a project with uv init, which creates a pyproject.toml, a lockfile, and virtual environment defaults. Add runtime dependencies with uv add (e.g., uv add requests Flask) and dev dependencies with uv add --dev (e.g., uv add --dev pytest pytest-cov). Install packages from the lockfile with uv sync, and run code or tools with uv run (e.g., uv run python main.py or uv run pytest).
When does pip still make sense instead of UV?
Pip still makes sense for existing production systems that assume pip as part of the system Python, Docker images where only pip is installed by default and you need a minimal footprint, and when maximum compatibility with older Python workflows is required.
Marcelo Bittencourt is a Software Engineer in Cheesecake Labs. Throughout his career, he has integrated AI into products, streamlined development workflows, and modernized legacy platforms, while also contributing to frontend initiatives using Angular, React, and Next.js.