Skip to main content
Guides

uv: The Fast Python Package Manager That Replaces pip, venv, pyenv and pipx

Pyobfuscate Team··10 min read
Quick Answer

uv is a single Rust binary from Astral (the team behind Ruff) that replaces pip, pip-tools, virtualenv, pyenv and pipx. In my tests on Python 3.14 it installed the same 8 packages 31× faster than pip with a warm cache (1.17 s vs 36.27 s) and created a virtualenv in 45 ms vs 6.1 s. Use uv pip install as a drop-in pip replacement, or uv init / uv add / uv run to manage a whole project — lockfile, virtualenv and Python version included. It's the fastest and most complete Python packaging tool in 2026, with a couple of honest caveats below.

Python packaging has been a pile of half-overlapping tools for a decade: pip to install, virtualenv to isolate, pip-tools to lock, pyenv to switch Python versions, pipx to run CLI tools. uv collapses all five into one binary — and because it's written in Rust, it's not incrementally faster, it's a different speed class. I'd read the "10–100× faster" claims and wanted real numbers, so I installed uv 0.12.1 (the latest, released 2026-07-31) and benchmarked it against pip on Python 3.14. Every number here is measured on my machine.

This is a practical tour of what uv does, backed by those benchmarks: uv as a drop-in pip replacement, uv as a full project manager (pyproject + lockfile + venv), and uv as a Python version manager that downloads interpreters for you. I'll also be straight about where it's still rough and whether it's worth switching in 2026.

What uv actually replaces

The mental model that makes uv click: it's one tool doing the job of five. Instead of learning pip *and* virtualenv *and* pyenv *and* pip-tools *and* pipx — each with its own flags and failure modes — you learn uv. Here's the mapping:

Old toolWhat it diduv equivalent
pipinstall packagesuv pip install / uv add
virtualenv / venvisolated environmentsuv venv (automatic in projects)
pip-toolslock dependenciesuv lock (automatic on uv add)
pyenvinstall/switch Python versionsuv python install / --python
pipxrun CLI tools in isolationuvx / uv tool run

It comes from Astral, the same team that makes Ruff (the linter that already ate flake8, isort and half a dozen others — we host it as our Ruff linter tool). Same playbook: take a slow, fragmented corner of the Python toolchain and replace it with one fast Rust binary. Worth knowing for context: OpenAI acquired Astral in March 2026, so uv now sits inside a much larger company — a governance change to keep an eye on, though the tool remains open source (Apache-2.0/MIT).

The headline: install speed (real benchmark)

Speed is the reason most people try uv, so I measured it properly. I installed the same 8 top-level packages — fastapi uvicorn sqlalchemy alembic httpx rich pydantic-settings requests, which resolve to 31 packages including transitive deps — into a fresh virtualenv each time, with both a cold cache (everything downloaded) and a warm cache (packages already local). Python 3.14.2, uv 0.12.1, pip 26.x:

Scenariopipuvuv is
Cold cache (fresh download)47.26 s7.90 s6.0× faster
Warm cache (already downloaded)36.27 s1.17 s31× faster
=== COLD cache (purged first, network download) ===
pip :  47.26 s
uv  :   7.90 s

=== WARM cache (packages already cached) ===
pip :  36.27 s
uv  :   1.17 s
uv speedup (warm): 31.0x faster
Real benchmark output — same 8 packages into fresh venvs

The warm-cache number is the one that matters day to day — it's what you hit every time you rebuild a venv, run CI with a cache, or uv add a package to an existing project. 1.17 seconds to resolve and install 31 packages. Three things make uv this fast:

  • A global content-addressed cache with hardlinks. uv doesn't re-copy a cached wheel into your venv — it hardlinks it. Installing an already-cached package is almost free, which is why the warm case collapses to ~1 s.
  • A parallel Rust resolver. pip resolves and downloads largely serially; uv resolves the whole graph and fetches in parallel across cores. That's most of the cold-cache win.
  • No per-command Python startup. pip is a Python program that pays interpreter startup and imports on every call; uv is a native binary that starts instantly.

The cold-cache gap (6×) is smaller than the warm-cache gap (31×) because cold installs are bound by your network download speed, which uv can't change — it just parallelizes it. The moment anything is cached, uv's architecture pulls away.

uv as a drop-in pip replacement

The lowest-commitment way to adopt uv: keep your existing workflow and just put uv in front of your pip and venv commands. The interface is intentionally familiar.

# make a virtualenv (replaces `python -m venv .venv`)
uv venv

# install into it (replaces `pip install`)
uv pip install fastapi uvicorn requests

# your existing requirements.txt just works
uv pip install -r requirements.txt

# compile a lockfile (replaces pip-tools' pip-compile)
uv pip compile requirements.in -o requirements.txt
The pip/venv workflow, but fast

Even venv creation alone is worth it. uv venv versus the stdlib python -m venv, best of three runs:

python -m venv :   6087 ms
uv venv        :     45 ms
uv is 135x faster at creating a venv
Real measurement — creating an empty virtualenv

Honest caveat on that 135×: python -m venv also bootstraps pip and setuptools *into* the new environment, which is most of its 6 seconds. uv venv creates a pip-less venv by design — you install with uv pip install, not pip. That's usually what you want, but if a script or tool shells out to pip inside the venv, add uv venv --seed to include it.

uv as a project manager (the real upgrade)

The drop-in mode is nice, but uv's project mode is where it replaces poetry/PDM and stops you thinking about virtualenvs at all. uv init scaffolds a modern project:

$ uv init myproj
Initialized project `myproj`

$ ls -a myproj
.git  .gitignore  .python-version  README.md  pyproject.toml  src/
uv init — a complete project in one command

Then uv add installs a dependency and updates pyproject.toml, writes a cross-platform uv.lock, and syncs the project's .venv — in one step. There's no separate "create venv", "activate", "install", "freeze" dance:

$ uv add fastapi
 + fastapi==0.141.1  + pydantic==2.13.4  + starlette==1.3.1  ...
# -> wrote uv.lock (158 lines) and created .venv automatically

$ uv tree
Resolved 11 packages in 1ms
myproj v0.1.0
└── fastapi v0.141.1
    ├── pydantic v2.13.4
    │   ├── pydantic-core v2.46.4
    │   └── ...
    └── starlette v1.3.1
        └── anyio v4.14.2

$ uv run python -c "import fastapi; print(fastapi.__version__)"
0.141.1                       # ran in the project venv — no `activate` needed
Real session — add a dependency, inspect the tree, run code

Two things to notice. `uv run` never makes you activate anything — it ensures the venv is in sync with the lockfile and runs your command inside it. And the whole thing is fast enough to feel free: adding a package to the warm project took 0.35 s, and verifying the lockfile is current (uv lock --check) took 28 ms. Locking stops being a chore you skip.

uv.lock is a universal lockfile — it resolves for every platform and Python version your project supports, so a teammate on macOS and CI on Linux install byte-identical dependency sets from the same file. Commit uv.lock; it's the reproducibility guarantee.

uv manages Python itself (goodbye pyenv)

This is the feature that surprised me most. uv doesn't just manage packages — it downloads and manages Python interpreters, replacing pyenv entirely. uv python list shows what's installed and what's a download away:

cpython-3.15.0b4-windows-x86_64      <download available>
cpython-3.14.6-windows-x86_64        <download available>
cpython-3.14.2-windows-x86_64        C:\...\Python314\python.exe
cpython-3.13.14-windows-x86_64       <download available>
cpython-3.12.13-windows-x86_64       <download available>
cpython-3.11.5-windows-x86_64        C:\...\Python311\python.exe
uv python list — installed and downloadable interpreters

You never install a Python manually again. Ask for a version you don't have and uv fetches it on demand. I ran a command targeting 3.12 without any 3.12 on my machine — uv downloaded CPython 3.12.13 and ran on it, in 0.47 s once cached:

$ uv run --python 3.12 --no-project python -c "import sys; print(sys.version.split()[0])"
ran on 3.12.13
Real output — uv fetches and runs an interpreter it did not have

And it respects your project's constraints. When I tried to run my requires-python = ">=3.14" project on 3.12, uv downloaded 3.12 but then refused to run — the guardrail working exactly as it should:

$ uv run --python 3.12 python -c "..."
Using CPython 3.12.13
error: The requested interpreter resolved to Python 3.12.13, which is
incompatible with the project's Python requirement: `>=3.14`
Real output — uv enforces requires-python

Finally, uvx (alias for uv tool run) replaces pipx — run a CLI tool in a throwaway isolated environment without installing it into your project. Astral's own Ruff, for instance:

$ uvx ruff --version
ruff 0.16.1                    # ephemeral env, nothing added to your project
uvx — run a tool without installing it

Should you switch? Honest tradeoffs

After benchmarking it, my answer is: for almost everyone, yes — but go in with eyes open. The upside is overwhelming (one tool, 30× faster, universal lockfile, no pyenv), so here are the honest reasons to hesitate:

  • It's pre-1.0 and moving fast. uv is still on 0.x versioning and ships breaking changes between minors occasionally. Pin the uv version in CI (uv self version / a version file) so a surprise update doesn't change your resolves.
  • `uv.lock` is uv's format, not a standard. It's excellent, but it locks you into uv for reproducible installs. uv can export to requirements.txt (and to the new PEP 751 pylock.toml) if you need an escape hatch, so this is manageable — just know the lockfile isn't portable to poetry/pip as-is.
  • pip-less venvs surprise some tools. As noted, uv venv omits pip; occasionally a build script or plugin expects pip to exist in the environment. uv venv --seed fixes it.
  • The OpenAI acquisition is new. Astral joined OpenAI in March 2026. The tool is open source and nothing has changed for users yet, but single-vendor control of core tooling is worth watching.

None of those outweigh a 31× speedup and the collapse of five tools into one. The migration is also low-risk because uv reads your existing requirements.txt and pyproject.toml — you can start with uv pip install today and adopt project mode whenever you're ready. If you write Python in 2026, uv is the default worth adopting.

Want to see what your dependencies actually contain before you ship them? Paste a package's Python into our Online Python Compiler to inspect it in a sandbox, and keep your own code clean with our Ruff linter and type checker — the same Astral-fast tooling philosophy uv is built on.

Inspect and lint your Python in the browser

Run any package or snippet in our Online Python Compiler — real CPython via WebAssembly, nothing uploaded — and keep your code clean with the same Astral-fast Ruff tooling uv is built on.

Open the Online Python Compiler

Free tools mentioned here

Frequently asked questions

What is uv in Python?

uv is an extremely fast Python package and project manager written in Rust by Astral (the makers of Ruff). It replaces pip, pip-tools, virtualenv, pyenv and pipx with a single binary — installing packages, creating virtualenvs, locking dependencies, managing Python versions, and running CLI tools. In my tests on Python 3.14 it installed a set of packages 31x faster than pip with a warm cache.

Is uv really faster than pip?

Yes, dramatically. In my benchmark installing the same 8 packages (31 including transitive deps) into a fresh virtualenv, uv was 6x faster than pip on a cold cache (7.90s vs 47.26s) and 31x faster on a warm cache (1.17s vs 36.27s). It also created a virtualenv in 45ms versus 6087ms for python -m venv. The speed comes from a Rust parallel resolver, a hardlinked global cache, and no per-command Python startup.

How do I use uv instead of pip?

Put uv in front of your existing commands: `uv venv` creates a virtualenv, `uv pip install <pkg>` installs into it, and `uv pip install -r requirements.txt` works with your existing requirements files. For a fuller workflow use project mode: `uv init` to scaffold, `uv add <pkg>` to add a dependency (which also updates pyproject.toml, writes uv.lock, and syncs the venv), and `uv run <cmd>` to run code in the project environment without activating anything.

Does uv replace pyenv?

Yes. uv installs and manages Python interpreters itself — `uv python list` shows installed and downloadable versions, `uv python install 3.12` fetches one, and passing `--python 3.12` to uv run will download that interpreter on demand if it's missing. In my test uv downloaded CPython 3.12.13 automatically and ran on it. It also enforces your project's requires-python constraint, refusing to run on an incompatible version.

What is the difference between uv and uvx?

uv is the main command for managing packages, projects, virtualenvs and Python versions. uvx is a shortcut for `uv tool run` — it runs a command-line tool in a temporary, isolated environment without installing it into your project, replacing pipx. For example `uvx ruff --version` runs Ruff in a throwaway environment. Use uv for your project's dependencies and uvx for one-off or global CLI tools.

Should I commit uv.lock to git?

Yes. uv.lock is a universal, cross-platform lockfile that pins exact versions for every platform and Python version your project supports, so everyone installs identical dependencies. Commit it for reproducible builds. Note that uv.lock is uv's own format rather than a shared standard, though uv can export to requirements.txt or the PEP 751 pylock.toml if you need portability to other tools.

Why does uv venv not include pip?

By design. uv creates a pip-less virtualenv because you're expected to install with `uv pip install`, which is far faster and doesn't need pip inside the environment. That's part of why `uv venv` is ~135x faster than `python -m venv`, which spends most of its time bootstrapping pip and setuptools. If a tool or script requires pip to exist in the venv, create it with `uv venv --seed` to include pip.

Keep reading