Python: Why uv is Amazing for Python Development

If you’ve spent any time with Python development, you know the drill, pip, venv, pyenv, pipenv, poetry, the ecosystem is fragmented. Every project seems to have its own opinion on how to manage dependencies and Python versions.

Enter uv, a blazingly fast Python package and project manager written in Rust, built by Astral. It replaces most of your Python toolchain with a single, cohesive tool.

What is uv?

uv is a drop-in replacement for pip, pip-tools, pipx, poetry, pyenv, twine, and virtualenv, all in one binary. It handles:

  • Installing and managing Python versions
  • Creating and managing virtual environments
  • Installing packages (fast, really fast)
  • Managing project dependencies with lockfiles
  • Running scripts with inline dependencies
  • Publishing packages to PyPI

Installation

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

# Or with pip (bootstrapping)
pip install uv

That’s it. One install and you’re set.

Why It’s a Game-Changer

1. It’s Incredibly Fast

uv is 10–100x faster than pip. It uses a global cache and parallel downloads, so installing packages feels instant, especially on repeated installs across projects.

# Benchmark: installing a typical data science stack
# pip:  ~45 seconds
# uv:   ~3 seconds

2. Manage Python Versions, No More pyenv

Forget pyenv. uv installs and manages Python versions natively:

# Install a specific Python version
uv python install 3.12

# Pin a project to a version
uv python pin 3.11

# List available versions
uv python list

3. Project Workflow (pyproject.toml First-Class)

uv treats pyproject.toml as the source of truth. Starting a new project is one command:

uv init my-project
cd my-project

This scaffolds a proper project with pyproject.toml, a src/ layout, and a lockfile.

# Add a dependency
uv add requests

# Add a dev dependency
uv add --dev pytest

# Remove a dependency
uv remove requests

# Sync the environment to the lockfile
uv sync

The lockfile (uv.lock) is cross-platform and deterministic, no more “works on my machine”.

4. Run Scripts with Inline Dependencies

This is one of my favorite features. You can declare dependencies inside a script and run it directly:

# /// script
# dependencies = ["httpx", "rich"]
# ///

import httpx
from rich import print

response = httpx.get("https://api.github.com")
print(response.json())
uv run my_script.py

uv automatically creates an isolated environment, installs the deps, runs the script, and cleans up. No manual venv needed.

5. Run Tools Without Installing Them Globally

Similar to npx in the Node.js world:

# Run ruff without installing it
uvx ruff check .

# Run a specific version of black
uvx black@24.3.0 .

uvx runs tools in ephemeral environments, your global Python stays clean.

6. Drop-in pip Compatibility

Already using pip? Just prepend uv:

uv pip install -r requirements.txt
uv pip freeze > requirements.txt
uv pip install -e .

Zero learning curve for the basics.

Real-World Workflow

Here’s how a typical project setup looks with uv:

# 1. Create a new project
uv init my-api
cd my-api

# 2. Pin the Python version
uv python pin 3.12

# 3. Add dependencies
uv add fastapi uvicorn
uv add --dev pytest httpx

# 4. Run the app
uv run uvicorn main:app --reload

# 5. Run tests
uv run pytest

# 6. Sync a colleague's clone
uv sync

From init to running in under a minute, no activation steps, no confusion.

Tips and Best Practices

  • Commit uv.lock to version control for reproducible builds
  • Use uv run instead of activating the venv manually, it always uses the right environment
  • Use uvx for one-off CLI tools like formatters, linters, and generators
  • Use .python-version (created by uv python pin) to communicate the project’s required Python version

Migrating from pip / venv

If you have an existing requirements.txt project:

uv init --no-workspace
uv add $(cat requirements.txt)
uv sync

Or if you’re coming from poetry, uv can import from pyproject.toml directly.

Takeaways

uv doesn’t just make Python development faster, it makes it simpler. One tool, one install, consistent behavior across machines and OSes.

If you’re still juggling pip, venv, and pyenv separately, give uv a try on your next project. You won’t go back.

The Python packaging ecosystem finally has a tool that feels like it was designed for developer experience.

Happy coding

/Emil