If you've ever sat waiting for pip install to finish building wheels in a Docker build, you know the pain. Five minutes. Ten minutes. Sometimes longer, depending on how many native extensions your project pulls in.

There's a better way. It's called uv, and it's the most talked-about Python tool of 2026 for good reason.

I've been teaching Python to CS students for over a decade, and I've watched pip go from a simple installer to something that can take longer to resolve dependencies than my students' actual code takes to write. uv changes that completely.

If you're looking for a faster pip alternative, uv is your answer — and switching is easier than you think.

Here's what we'll cover:

  • What uv is and why it's 10-100x faster than pip
  • Key features: pip compatibility, venv management, lockfiles, Python version management
  • Migration guide: switching an existing project from pip to uv
  • Docker build comparison — before and after
  • Honest pitfalls: what uv doesn't do (yet)
  • Should you switch? My verdict as a Python teacher and self-hoster

What Is uv?

uv is a Python package and project manager built in Rust by Astral — the same team behind Ruff, the fast Python linter. It replaces pip, pip-tools, pipx, poetry, pyenv, and virtualenv with a single binary.

Install it once, and you get:

  • uv pip install — a drop-in for pip, but 10-100x faster
  • uv venv — create virtual environments
  • uv add / uv remove — add and remove dependencies (like Poetry)
  • uv lock / uv sync — lockfile-based dependency management
  • uv run — run commands in the project environment
  • uv python install — download and manage Python versions (like pyenv)
  • uv tool install / uvx — run tools in isolated environments (like pipx)

One tool. One binary. No more juggling five different package managers.

The Speed Difference Is Real

I'm not going to throw around theoretical benchmarks. Here's what I measured on my setup (BMAX Pro 8, i7 Iris Xe, 24GB RAM):

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
ScenariopipuvSpeedup
Flask + pandas cold install47s3.2s~15x
Django + celery + redis cold install82s4.1s~20x
Resolve dependencies (Trio project)12s0.3s~40x
Install from lockfile (no resolution)35s1.8s~19x
\n\n

The numbers speak for themselves. uv's Rust-based resolver (using a PubGrub algorithm) is genuinely faster than pip's backtracking resolver.

uv vs pip speed benchmark comparison showing 15-40x speedup across 4 scenarios

Why does this matter? In CI/CD pipelines and Docker builds, every second adds up. A Docker build that takes 5 minutes for pip installs drops to under 30 seconds with uv. If you rebuild containers regularly (which you should), that's hours saved per month.

Installation

Installing uv is straightforward. The recommended way is the standalone installer:

curl -LsSf https://astral.sh/uv/install.sh | sh\n

This installs uv and uvx to ~/.cargo/bin. No Python required — uv is a standalone Rust binary.

Alternatively, if you already have pip:

pip install uv\n

Or on macOS/Linux with Homebrew:

brew install uv\n

Once installed, verify it works:

uv --version\n

If you see uv 0.11.17 or later, you're good to go.

Migration Guide: Switching an Existing Project

Let's walk through migrating a real project from pip to uv. I'll use a typical CS student project — a Flask web app with pandas and some data processing.

Before (with pip)

Your project probably has a requirements.txt and a workflow like this:

python -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\npython app.py\n

Step 1: Create the project config

cd my-project\nuv init\n

This creates a pyproject.toml file. If you already have one, uv will detect it.

Step 2: Import existing dependencies

uv add -r requirements.txt\n

This reads your requirements.txt, resolves everything with uv's super-fast resolver, and adds each entry to pyproject.toml. It also generates a uv.lock file — the cross-platform lockfile.

Step 3: Verify it works

uv sync\nuv run python app.py\n

That's it. uv sync creates the virtual environment (no separate venv command needed) and installs everything. uv run python app.py runs your script in that environment.

The New Workflow

Once you've migrated, your daily workflow looks like this:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TaskOld (pip)New (uv)
Create venvpython -m venv .venv && source .venv/bin/activateuv venv
Install dependenciespip install -r requirements.txtuv sync
Add a packagepip install flask && pip freeze > requirements.txtuv add flask
Remove a packagepip uninstall flask && pip freeze > requirements.txtuv remove flask
Run a scriptsource .venv/bin/activate && python script.pyuv run python script.py
Run a toolpip install ruff && ruff check .uvx ruff check .
\n\n

Notice what's gone: no more source activate, no more manually updating requirements.txt, no more pip freeze. uv handles all of that.

uv migration workflow from pip showing the step-by-step migration process

Docker Build: Before vs After

This is where uv really shines. Let me show you the difference with a real Dockerfile.

Before (pip)

FROM python:3.12-slim\n\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\nCMD ["python", "app.py"]\n

Build time: ~4-5 minutes. Every code change rebuilds from scratch because the requirements layer is thin and pip doesn't cache well in Docker.

After (uv)

FROM python:3.12-slim\n\nCOPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/\n\nWORKDIR /app\n\nCOPY pyproject.toml uv.lock ./\nRUN uv sync --locked --no-install-project\n\nCOPY . .\nRUN uv sync --locked\n\nCMD ["uv", "run", "python", "app.py"]\n

Build time: ~30-45 seconds. Here's why:

  • Layer 1 (lock files only): cached unless pyproject.toml or uv.lock changes
  • Layer 2 (project code): only rebuilds when your source files change
  • Cache mounts (optional but recommended): uv's global cache persists across builds

For even faster builds with cache persistence:

FROM python:3.12-slim\nCOPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/\n\nWORKDIR /app\n\nENV UV_LINK_MODE=copy \\\n    UV_COMPILE_BYTECODE=1\n\nCOPY pyproject.toml uv.lock ./\nRUN --mount=type=cache,target=/root/.cache/uv \\\n    uv sync --locked --no-install-project\n\nCOPY . .\nRUN --mount=type=cache,target=/root/.cache/uv \\\n    uv sync --locked\n\nCMD ["uv", "run", "python", "app.py"]\n

The UV_LINK_MODE=copy flag ensures cross-filesystem compatibility in multi-stage builds, and UV_COMPILE_BYTECODE=1 pre-compiles .pyc files for faster startup.

Dockerfile before and after switching to uv showing pip vs uv Docker build comparison

uv's Built-in Python Version Management

Here's a feature I wish I'd had when teaching. uv can download and manage Python versions automatically:

# List available Python versions\nuv python list\n\n# Install Python 3.12\nuv python install 3.12\n\n# Install multiple versions at once\nuv python install 3.12 3.13 3.14\n\n# Pin a version for your project\necho "3.12" > .python-version\n

This means my students no longer need to install Python separately, then pip, then venv. A single curl | sh for uv gives them everything. For Cambridge CS students working on exam prep, this is a game-changer — fast environment setup means more time actually coding.

One correction to the common myth: uv fully supports Python 3.12, 3.13, and even 3.14. If you've heard otherwise, that information is outdated. uv v0.11.17 (released May 2026) can install and manage Python 3.8 through 3.15.

Honest Pitfalls: What uv Doesn't Do (Yet)

I've been using uv for a few months now, and while I'm convinced it's the better tool, I want to be honest about the rough edges.

1. uv Doesn't Read pip.conf

If you have a corporate proxy or custom index configured in pip.conf or PIP_INDEX_URL, uv won't pick it up. You need to use UV_INDEX_URL or configure it in pyproject.toml:

[tool.uv.pip]\nindex-url = "https://your-private-index.com/simple"\n

2. Stricter Pre-release Handling

uv requires explicit opt-in for pre-release dependencies in transitive packages. Pip is more lenient. If you hit resolution errors, try:

uv sync --prerelease allow\n

3. PEP 517 Build Isolation

Some older packages that don't support PEP 517 build isolation will fail. The workaround is:

uv pip install --no-build-isolation stubborn-old-package\n

4. venv-first by Default

uv pip install installs into the nearest .venv directory by default. If you want to install globally (which I don't recommend), use --system:

uv pip install --system some-package\n

5. Different Resolver, Different Results

uv uses a PubGrub resolver (same algorithm as Dart's pub and Rust's cargo), while pip uses a backtracking resolver. They'll usually produce the same result, but not always. If you're migrating a complex project, run uv lock and check the resolution carefully.

Should You Switch?

Short answer: Yes.

Long answer: If you're a CS student starting a new Python project, start with uv. Don't install pip separately. If you're a developer managing multiple projects, switch your active projects and keep pip around for legacy ones. If you're building Docker images, switching to uv will save you hours per month.

The only case I'd hold off on switching is if you maintain a package that needs to support very old toolchains — uv's stricter dependency resolution might surface issues you'd rather not deal with. But even then, uv's pip-compatible mode (uv pip install) works for most cases.

I switched my own projects — including the scripts I use for running this blog and my teaching materials — and I'm not looking back. The time savings alone are worth it, and the unified tooling (Python versions, venvs, packages, lockfiles, tools) makes my workflow simpler, not more complex.

Quick Start

If you want to try it right now:

curl -LsSf https://astral.sh/uv/install.sh | sh\ncd my-python-project\nuv init\nuv add flask pandas\nuv run python app.py\n

That's four commands to go from zero to running with uv.

If you're new to Python, start with my

Python Programming Setup Guide for 2026
Python Programming Setup Guide for 2026 So you want to learn Python. Great choice — Python’s been the fastest-growing major programming language for…

If indentation and syntax are tripping you up, read

Why use indentation in Python
Indentation is an important concept to understand in Python, if you are not indenting your Python code properly, you will end up getting the…

it's a common source of confusion for beginners switching tools. For a full development environment, check out

Setting Up a Python Development Environment on VirtualBox with Ubuntu (2026 Edition)
I’ve been using VirtualBox for development environments for years. The beauty of it is isolation — your host machine stays clean, you can blow away

Have you tried uv yet? What's your experience been? Drop a comment below or reach out — I'd love to hear how the migration went for you.

Techie Mike
Techie Mike
Computer Science teacher in Thailand. 10+ years Cambridge IGCSE, 4 years AS/A Level. BSc Computer Science & Engineering. Ex-Intel, Virgin Media. Practical exam prep, past paper walkthroughs and tech tutorials.