I have a long history of Python tooling pain. Over the last decade I’ve used pip + virtualenv, then pyenv-virtualenv, then pipenv (briefly, regrettably), then Poetry for libraries, then pipx for global CLI tools, then conda for one specific data project that demanded it. At one point my ~/.zshrc had four different Python-related path manipulations and I couldn’t have told you what any of them did.
Six months ago I deleted all of it and switched to uv, the Python package manager from Astral (the people behind Ruff). I haven’t reinstalled any of the others. This is a real opinionated review based on actually shipping code with it, not a fluff post about benchmarks.
What uv Actually Is
uv is a single Rust binary that does the jobs of pip, pip-tools, pipx, pyenv, virtualenv, and Poetry. That’s an absurd marketing claim and also basically true. It is not a thin wrapper that shells out to those tools; it reimplements the dependency resolver, the installer, the Python version manager, and the lockfile format from scratch in Rust.
The headline feature is speed. uv is 10x to 100x faster than pip for the operations that take time. A fresh uv pip install of a moderate scientific stack (numpy, pandas, scikit-learn, matplotlib) into an empty venv takes about 4 seconds on my laptop. The equivalent pip install takes 45 seconds. On CI, where you’re doing this in every job, this compounds into real money and real waiting.
But speed is not why I switched. Speed is a nice-to-have. Single-binary tool consolidation is why I switched.
The Tools It Killed for Me
pyenv
pyenv was the right answer for years. Install any Python version, manage a .python-version file per project, get the right interpreter automatically. The problem with pyenv is that it compiles Python from source on install, which takes minutes and occasionally fails with cryptic OpenSSL errors that you spend an afternoon debugging.
uv has uv python install 3.13. It downloads a precompiled standalone CPython build (the python-build-standalone project, which Astral has since adopted) in about three seconds. The version is fully self-contained — no system library dependencies, no OpenSSL surprises, works the same on every machine. I haven’t compiled Python in six months. I don’t miss it.
uv python list shows installed and available versions. uv python pin 3.13 writes a .python-version. Same interface as pyenv, no compilation.
pipx
pipx existed to install Python CLI tools (black, ruff, httpie, awscli) into isolated environments so they didn’t conflict with your project venvs. Genuinely useful, but it was one more tool to install and remember.
uv tool install <package> does the same thing. uv tool list, uv tool upgrade --all, uv tool run <command> (or the shortcut uvx <command>). The killer move is uvx, which runs a tool in an ephemeral environment without installing it at all — like npx for Python. I use uvx ruff check in projects where I haven’t bothered to add ruff as a dev dependency. Just works.
pip + virtualenv
uv venv creates a venv 80x faster than python -m venv. uv pip install <package> is a drop-in replacement for pip with the same CLI. If you do nothing else, you can use uv as “fast pip” and get a noticeable quality of life improvement.
The thing I appreciate is that uv pip doesn’t try to be cleverer than pip. It mimics the interface exactly. If pip would install something, uv pip installs the same thing. You can drop it into existing projects without changing anything.
Poetry
This is the controversial one. Poetry has been the de facto modern Python project manager for years. I used it on every library I shipped. It has a beautiful UX, a good lockfile, and a working build backend.
uv replaces Poetry with uv init, uv add <package>, uv lock, uv sync, and uv build. The interface is similar enough that you can switch in a day. The differences I noticed:
uv is faster at everything. Locking is faster, syncing is faster, adding a dependency is faster. Poetry has gotten faster too, but it’s not close.
uv uses standard pyproject.toml with PEP 621 metadata. Poetry uses its own [tool.poetry] table. With uv, your pyproject.toml is portable — pip, hatch, flit, anything modern can read it. With Poetry, you’re in Poetry-land.
The lockfile is portable. uv.lock works on Linux, macOS, Windows, multiple Python versions, multiple architectures, all from one file. Poetry’s lockfile has gotten better at this but historically caused real pain on cross-platform projects.
Dependency groups are simpler. uv add --dev pytest puts pytest in [dependency-groups.dev]. The structure is dead obvious. Poetry’s optional dependencies + extras + dev dependencies took me an embarrassing number of re-reads of the docs over the years.
What Poetry still does better: the documentation is more thorough. uv’s docs are good but assume you know what a Python project looks like. Poetry walks you through it.
pip-tools
For projects where I wasn’t ready to commit to a full project manager, I used pip-tools (pip-compile and pip-sync) to manage a requirements.in → requirements.txt flow. uv handles this with uv pip compile requirements.in -o requirements.txt and uv pip sync requirements.txt. Same workflow, one binary.
What I Actually Do Day to Day
Starting a new project:
uv init myproject
cd myproject
uv add fastapi httpx
uv add --dev pytest pytest-asyncio ruff
uv run pytest
That’s the whole flow. No venv to activate (uv does it for you on uv run). No pip install -e .. No python -m venv .venv. The pyproject.toml is standard PEP 621. The lockfile is uv.lock and I commit it.
For a one-off script that needs requests:
uv run --with requests python -c "import requests; print(requests.get('https://api.github.com').status_code)"
That installs requests into an ephemeral environment, runs the script, throws the environment away. I used to write throwaway scripts and then forget I had a .venv lying around. Now there’s nothing to clean up.
For a library I’m publishing:
uv build
uv publish
uv has its own build backend (uv_build) that’s faster than setuptools/hatch and supports the standard PEP 517 interface. I switched a small library to it and noticed nothing different about the published wheel except that the build was 4x faster.
Where It’s Still Rough
uv isn’t perfect. Three things I’ve hit.
The error messages on dependency resolution failures are improving but can still be cryptic. When two packages have incompatible requirements, uv tells you exactly which versions are incompatible, which is more than pip used to do, but the output is dense and you have to read it carefully. Poetry’s resolution errors are slightly easier to scan.
Some packages with weird build requirements still surprise it. Anything that needs custom C compilation with non-standard flags can require setting UV_CONCURRENT_DOWNLOADS=1 or similar workarounds. This is rare but happens with old scientific packages.
The Python community is still catching up. Some Poetry-first tooling (e.g. certain VS Code extensions, some CI templates) doesn’t auto-detect uv projects yet. You’ll occasionally have to tell a tool “yes this is a Python project, use the venv at .venv/.” This is getting better fast — most major editors now recognize uv.lock.
Should You Switch?
If you’re starting a new project today, yes. There’s no reason to start a 2026 Python project with anything else. The tooling is fast, the lockfile is good, the dependency story is sane, and you only need one binary.
If you have an existing Poetry project, the switch is a one-evening effort. pyproject.toml migration is mostly mechanical. The lockfile regenerates clean. CI pipelines simplify (one uv sync replaces a half-dozen pip/poetry steps).
If you’re a “pip + venv from a shell script” person who’s resisted modern tooling entirely, uv is the tool I’d use to break that streak. The friction is the lowest it’s ever been.
If you’re deep in conda for scientific work with native dependencies, conda still has a niche. uv doesn’t replace conda for non-Python packages (CUDA toolkits, MKL, etc.). For pure-Python scientific work, uv is faster and saner.
The Bottom Line
The promise of uv is consolidation: one binary, learned once, that handles every Python tooling task. The reality matches the promise. I uninstalled pyenv, pipx, Poetry, pip-tools, and virtualenv six months ago and haven’t reinstalled any of them. My ~/.zshrc is shorter. My CI is faster. My new projects bootstrap in 30 seconds.
This is the first time in fifteen years of Python that I’ve felt like the tooling was actually pleasant. If you’ve been waiting to see if uv was a fad before switching, it’s not. Switch.