The Python packaging ecosystem is famously broken. Between pip, pipenv, poetry, pyenv, and virtualenv, you need five different tools to do what npm does in one. Enter UV — a single Rust-powered replacement that's 10-100x faster than pip and actually understands modern Python development.
What UV Is
UV is a Python package manager written in Rust by Astral, the team behind Ruff. It's designed as a drop-in replacement for pip, but it also handles virtual environments, lockfiles, Python version management, and project scaffolding. Think Cargo for Python, but one that actually exists and works.
The core insight is simple: Python packaging tools have been rewritten in Python, which means they're slow and have complex bootstrap requirements. UV is written in Rust, ships as a single binary, and doesn't need Python installed to manage Python.
Why UV Matters
Speed isn't just a nice-to-have when you're waiting for dependencies to resolve. A typical Django project takes pip 45 seconds to install fresh. UV does it in 1.2 seconds. That's not incremental improvement — that's changing how you work.
But the real win is consolidation. Instead of juggling pip + venv + pip-tools + pipx, you have one tool that handles everything. Create a project, add dependencies, run scripts, manage Python versions — all with consistent commands that actually make sense.
UV also introduces proper lockfiles to the Python world. No more "works on my machine" because someone has a different numpy version. Lock your dependencies once, reproduce everywhere.
Hands On
Installing UV takes one command:
curl -LsSf https://astral.sh/uv/install.sh | sh
Creating a new project feels refreshingly simple:
$ uv init myapp
$ cd myapp
$ uv add fastapi uvicorn
That's it. UV created a virtual environment, installed your dependencies, and generated a proper pyproject.toml with a lockfile. Compare that to the pip equivalent:
$ python -m venv myapp
$ cd myapp
$ source bin/activate # source .venv/bin/activate on Linux/Mac
$ pip install fastapi uvicorn
$ pip freeze > requirements.txt # hope this is reproducible
Running scripts is equally clean. UV can manage dependencies inline:
# script.py
# /// script
# dependencies = ["requests", "click"]
# ///
import requests
import click
@click.command()
def main():
response = requests.get("https://httpbin.org/json")
print(response.json())
$ uv run script.py
UV reads the dependency metadata, creates an isolated environment, installs packages, and runs your script. No global pollution, no manual venv management.
The pip interface works exactly as expected: uv pip install package is faster pip. Your muscle memory transfers immediately.
Honest Verdict
UV delivers on its promises. It's genuinely faster, the commands are logical, and it solves real frustrations with Python tooling. The lockfile support is solid, and being able to manage Python versions eliminates another pain point.
There are rough edges. The documentation assumes familiarity with Python packaging concepts that many developers struggle with. Error messages are sometimes less helpful than pip's. And if you're already committed to poetry or pipenv workflows, migration isn't automatic.
But those are minor compared to the core value. UV is what Python packaging should have been from the start. It's fast enough to change how you work, comprehensive enough to replace your entire toolchain, and reliable enough to trust in production.
For new Python projects, there's no reason to choose anything else. For existing projects, the migration is usually worth the effort.
Go Try It
Start with a throwaway project. Run uv init testproject && cd testproject, add some dependencies with uv add, and see how it feels. The speed difference is immediately obvious, but the real benefit is the workflow simplification.
If you like what you see, check UV's documentation for migration guides and advanced features. Your future self will thank you.
More tools at Just Me and Linux. Compiled by AI. Proofread by caffeine. ☕