What Is uv? The Fast Python Package Manager

Photo: Daniil Komov / Pexels
If you've spent the last decade waiting for pip install to resolve dependencies, uv is the tool that finally fixed it. Released in February 2024 by Astral — the company behind the Ruff linter, and now part of OpenAI following a March 2026 acquisition — uv is a Python package and project manager written in Rust. It replaces pip, venv, pyenv, pip-tools, pipx, twine, and large chunks of Poetry with a single binary.
The number everyone quotes is Astral's own benchmark: 10 to 100 times faster than pip, and roughly 80 to 115 times faster on cold installs where nothing is cached yet (Astral, uv: Unified Python packaging). uv has grown into one of the most widely used pieces of Python tooling built in the last decade, with over 126 million downloads a month as of early 2026 (Simon Willison, "Thoughts on OpenAI acquiring Astral and uv/ruff/ty," March 19, 2026). This piece explains what uv actually replaces, why it's fast, how its two interfaces work, and what changed when its maker was bought by one of the biggest AI companies in the world.
What uv actually replaces
Before uv, a typical Python setup required five or six separate tools working together, each with its own quirks, its own config file format, and its own failure modes. You'd install pyenv to manage Python versions, python -m venv to create a virtual environment, pip to install packages, pip-tools or Poetry to lock dependency versions, and twine to publish a package to PyPI. Each handoff between tools was a place things could silently break.
uv collapses that chain into one binary with one consistent command syntax:
| Job | Old tool | uv equivalent |
|---|---|---|
| Install packages | pip install |
uv pip install or uv add |
| Create virtualenv | python -m venv |
uv venv |
| Manage Python versions | pyenv |
uv python install 3.13 |
| Lock dependencies | pip-compile / poetry lock |
uv lock |
| Run scripts in env | poetry run |
uv run |
| Sync env to lockfile | pip-sync / poetry install --sync |
uv sync |
| Install CLI tools globally | pipx install |
uv tool install / uvx |
| Build and publish a package | python -m build + twine upload |
uv build + uv publish |
Table: The tools uv consolidates into a single Rust binary.
You no longer install pyenv separately, activate a venv by hand, then run pip install -r requirements.txt and hope the lockfile is current. One tool, one command per task, and the commands are designed to feel familiar if you've used pip or Poetry before.
Installation
Installing uv doesn't require Python to already be present on the machine, which matters because uv is also the tool that installs Python for you.
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or via pip itself
pip install uv
# Or Homebrew
brew install uv
The standalone installer drops a single ~30 megabyte binary at ~/.local/bin/uv (Astral uv documentation). That size is worth pausing on: pip plus pip-tools plus virtualenv plus pyenv, installed and configured the traditional way, easily exceeds that footprint once you count the Python interpreter dependencies each of those tools drags in. uv ships as a static Rust binary with no runtime dependencies of its own.
Two interfaces: pip-compatible and project-native
uv deliberately exposes two different surfaces, and understanding which one you're using matters, because they solve different problems.
1. uv pip — drop-in pip replacement
If you have an existing project with a requirements.txt, this works today with essentially zero changes to your workflow:
uv venv # create .venv
source .venv/bin/activate
uv pip install -r requirements.txt # roughly 10x faster than pip
uv pip install django pandas
uv pip freeze > requirements.txt
Same commands, same flags, same output format as pip. You are simply swapping the binary you invoke — pip install becomes uv pip install — and everything downstream (CI scripts, Dockerfiles, onboarding docs) keeps working unmodified.
2. uv project commands — Poetry-style workflow
For new projects, uv treats pyproject.toml as the single source of truth and maintains a lockfile called uv.lock:
uv init my-project # creates pyproject.toml + .python-version
cd my-project
uv add fastapi 'sqlalchemy>=2' # adds deps + updates lock
uv add --dev pytest ruff # dev-only dependencies
uv remove sqlalchemy
uv sync # installs exactly what's in uv.lock
uv run pytest # runs inside the managed env, no activate needed
uv lock --upgrade # bump locked versions
There's no poetry install, no poetry shell. uv run resolves and activates the correct environment invisibly, every time, which removes an entire category of "works on my machine" bugs caused by someone forgetting to activate a venv before running a script.
How does uv decide which interface to use?
uv looks for a pyproject.toml with a [project] table and a uv.lock file. If both exist, project commands (uv add, uv sync, uv run) operate against that lockfile. If you invoke uv pip, it always behaves like classic pip regardless of what other files exist, which is why the two modes can coexist in the same repository during a migration.
Why it's so fast
uv's speed comes from four compounding design choices, not one silver bullet.
Rust plus parallel I/O. Dependency resolution and package downloads happen concurrently across many threads. pip's resolver, by contrast, is largely serial and re-implemented in pure Python, which is inherently slower at CPU-bound tasks like constraint solving.
A global cache with hard links. Every package version downloads to a shared machine-wide cache exactly once. When uv builds a new virtual environment, it hard-links the files from that cache instead of copying or re-downloading them. Installing pandas into a fresh venv, once it's cached anywhere on the machine, takes milliseconds rather than seconds.
The PubGrub resolver. uv uses the same resolution algorithm as Poetry — PubGrub, originally designed for the Dart package manager — but reimplements it in Rust with aggressive memoization, so repeated resolution work across similar dependency graphs doesn't get redone from scratch.
Zero-copy installs where the platform allows it. Wheel files are mapped directly into target environments instead of being fully re-extracted, when the underlying filesystem supports it.
Astral's published benchmark for installing the Trio async library with a warm cache tells the story clearly:
| Tool | Time (warm cache) |
|---|---|
| pip | 3.41 s |
| pip-tools | 4.04 s |
| Poetry | 5.10 s |
| uv | 0.07 s |
Table: Astral benchmark, warm-cache install of Trio. Source: uv benchmark methodology, Astral.
That 0.07-second figure is roughly 48 times faster than pip in this specific benchmark. Cold-cache numbers (nothing downloaded yet) show a smaller but still substantial gap — pip around 8.5 seconds versus uv around 1 second for the same install — because cold installs are bottlenecked by network transfer rather than resolver speed. Independent benchmarking cited in 2026 coverage puts cold-cache speedups in the 80 to 115x range across broader test suites, reflecting improvements Astral shipped through 2025 (w3resource, "Astral Python 2026," 2026).
Think of it like the difference between a librarian who re-walks the entire building to find each book you ask for, versus one who keeps a running map of exactly where every book sits and can grab three at once. pip is the first librarian; uv is the second, and it never forgets where it already looked.
Python version management
This is the feature that puts the final nail in pyenv's coffin for a lot of teams, because it removes the biggest pain point of managing multiple Python versions: compilation time.
uv python install 3.12 3.13 # downloads pre-built CPython
uv python list # what's installed and available
uv python pin 3.13 # writes .python-version
uv run --python 3.11 script.py # one-off run in a different version
uv installs Python using Astral's own pre-built CPython distributions, a project called python-build-standalone (python-build-standalone, GitHub). That's the key difference from pyenv, which typically compiles CPython from source on your machine — a process that can take several minutes and requires system build dependencies like OpenSSL headers and a C compiler to already be correctly configured. uv's approach downloads a binary and unpacks it, which takes seconds.
What happens if uv can't find the Python version I asked for?
By default, uv downloads it automatically from the python-build-standalone release channel rather than erroring out. You can disable this with --no-python-downloads if you want uv to only use interpreters already present on the system, which matters in locked-down or air-gapped environments.
Workspaces for monorepos
For projects with multiple internal packages — a common pattern in larger codebases with a shared library and several services — uv supports Cargo-style workspaces declared in pyproject.toml:
[tool.uv.workspace]
members = ["packages/*"]
Each package keeps its own pyproject.toml, but the whole workspace shares one uv.lock and, by default, one virtual environment. This is functionally equivalent to npm or pnpm workspaces in the JavaScript ecosystem, and it solves the same problem: keeping internal package versions consistent without publishing them to a registry just to depend on each other. Poetry added comparable workspace support starting in version 1.2, but uv's implementation was built around workspaces from the start rather than retrofitted.
uv vs pip vs Poetry vs Pipenv vs PDM
| Feature | uv | pip | Poetry | Pipenv | PDM |
|---|---|---|---|---|---|
| Language | Rust | Python | Python | Python | Python |
| Install speed (relative) | 1x | 10-100x slower | 20-70x slower | 30-80x slower | 5-30x slower |
| Lockfile | uv.lock | No (pip alone) | poetry.lock | Pipfile.lock | pdm.lock |
| pyproject.toml support | Yes | Limited | Yes | No | Yes |
| Python version management | Built-in | No | No | No | No |
| Drop-in pip replacement | Yes (uv pip) |
— | No | No | Partial |
| Workspaces / monorepo | Yes | No | Yes (1.2+) | No | Yes |
| Inline script dependencies | Yes | No | No | No | No |
| PEP 582 (no venv) | No | No | No | No | Yes |
| Backed by | Astral / OpenAI | PSF | Open source community | PyPA | Open source community |
| First release | Feb 2024 | 2008 | 2018 | 2017 | 2019 |
Table: Feature comparison of the five most common Python packaging tools as of mid-2026.
The honest summary: uv is faster than everything else by roughly an order of magnitude, covers more ground with a single binary, and by 2026 is stable enough to run in production CI pipelines at large organizations. Poetry's plugin ecosystem is still somewhat more mature after eight years of community contributions. PDM's PEP 582 support — running Python projects without a virtual environment at all, using a local __pypackages__ directory instead — remains a genuinely different approach that uv hasn't adopted.
The OpenAI acquisition: what changed in 2026
On March 19, 2026, OpenAI announced it was acquiring Astral, the company behind uv, Ruff, and the newer type checker ty (OpenAI, "OpenAI to acquire Astral," March 2026). The Astral team joined OpenAI's Codex division, the group building OpenAI's autonomous coding agent, rather than being folded into a general engineering org — a signal that OpenAI sees fast, reliable Python tooling as core infrastructure for AI coding agents that write and execute Python constantly.
Astral co-founder and CEO Charlie Marsh said the company would continue developing uv and Ruff as open source projects after the deal closed: "We'll keep building in the open" (Simon Willison, March 19, 2026). Astral engineer Douglas Creager addressed the obvious worry — a single AI lab now controls infrastructure millions of developers depend on daily — by pointing to the tools' permissive open source licenses: if OpenAI ever mismanages the project, the community can fork it and continue independently. That's a real safety valve, but it's also worth noting explicitly that it's a worst-case fallback, not a guarantee that stewardship stays healthy.
It's a similar move to Anthropic's December 2025 acquisition of the Bun JavaScript runtime, part of a broader pattern of AI companies buying up the developer tooling their coding agents rely on most heavily. Whatever you think of the consolidation, the practical effect for a working Python developer in mid-2026 hasn't changed: uv still installs the same way, uv.lock still means the same thing, and the CLI commands documented above are unchanged by the acquisition.
Is uv still free and open source after the OpenAI deal?
Yes. uv remains released under the same permissive open source license (MIT/Apache dual license) it always used. OpenAI's stated commitment, repeated by Astral leadership, is to continue development in the open rather than closing the source or gating features behind a paid product.
Real-world CI example
Here's what a typical Docker layer for a Python service looks like with uv, the kind of pattern now common in production deployments:
FROM python:3.13-slim
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
COPY . .
CMD ["uv", "run", "uvicorn", "app:app", "--host", "0.0.0.0"]
The --frozen flag on uv sync refuses to update the lockfile if pyproject.toml and uv.lock have drifted out of sync — the build fails loudly instead of silently installing different versions than what's committed. That's exactly the behavior you want in a CI pipeline, where a silent version drift between a developer's laptop and the deployed container is the kind of bug that costs an afternoon to track down. For teams building broader Python automation workflows, this same speed advantage compounds across every step of a CI run, from installing test dependencies to spinning up ephemeral tooling environments.
If you're evaluating your broader Python data tooling stack alongside uv, see our guide on Python for data science, and if your workloads lean toward fast local analytics rather than package management, what DuckDB actually does is a useful companion read — both tools share uv's philosophy of doing one job in-process, extremely fast, without extra infrastructure.
When to stick with pip
uv isn't mandatory for every situation, and there are a handful of legitimate reasons to hold off:
- You're maintaining a library distributed via PyPI and don't want to add a build-tool dependency your downstream users have to reason about.
- You work in a regulated environment where vendoring a third-party Rust binary triggers a security review process you'd rather avoid this quarter.
- You're contributing to an established project that already pins pip plus
requirements.txt, and changing the toolchain requires a team vote or a formal RFC process. - Your deployment target has no internet access and no pre-approved mirror for Astral's Python builds, making
uv python installa non-starter without extra infrastructure work.
Outside those specific cases, uv is very likely the better default for new Python work in 2026.
What people get wrong about uv
The most common misconception is that uv pip install behaves identically to Poetry or PDM's dependency resolution model — it doesn't. uv pip intentionally mimics pip's flat, non-locking behavior by default; if you want reproducible, cross-platform locked installs, you need the project-mode commands (uv add, uv sync), not uv pip. Mixing the two modes in the same project without understanding the distinction is a frequent source of "why did my teammate get a different pandas version" bugs.
A second misconception is that switching to uv requires rewriting your requirements.txt into a pyproject.toml immediately. It doesn't. uv pip install -r requirements.txt works against your existing files unchanged — the project-native workflow is a separate, optional upgrade path you can adopt later, or never, if requirements.txt still suits your team.
A third: people assume uv's speed comes primarily from caching, and that a cold, uncached install won't be meaningfully faster than pip. That's wrong by a wide margin — even on a fully cold cache with nothing pre-downloaded, uv's parallel resolver and downloader still substantially outpace pip's serial approach, just less dramatically than the eye-popping warm-cache numbers suggest.
FAQ
Q: Is uv production-ready?
A: Yes. uv has been in wide production use since 2024, and as of 2026 it's used in CI pipelines at organizations including Hugging Face, and cited among major open source projects that have adopted Astral's tooling (w3resource, 2026). The on-disk formats — uv.lock and .python-version — are stable and safe to commit to version control.
Q: Will my pip plugins work with uv?
A: uv pip mimics pip's command-line surface but does not load pip plugins, since it's a separate Rust implementation rather than a wrapper around pip itself. Most users don't rely on pip plugins; if you do, run pip through a uv-managed Python interpreter instead: uv run pip ....
Q: Does uv work with private package indexes?
A: Yes. --index-url, --extra-index-url, and authentication via UV_INDEX_* environment variables or a .netrc file all work as expected. Keyring-based authentication is supported via uv pip --keyring-provider.
Q: How does uv differ from Rye? A: Rye was an earlier, experimental project by former Flask creator Armin Ronacher exploring the same "one tool for everything" idea. Astral took over stewardship of Rye's direction, and uv became its spiritual successor; Rye's own documentation now recommends migrating to uv.
Q: Can I publish packages with uv?
A: Yes. uv build and uv publish shipped in late 2024 and replace the older python -m build plus twine upload combination for building and uploading packages to PyPI.
Q: Does uv require pyproject.toml?
A: Only for project-mode commands (uv add, uv sync, uv lock). uv pip install works against any environment, requirements.txt file, or setup.py-based project without changes.
Q: Who owns uv now that OpenAI acquired Astral? A: OpenAI owns Astral as of the deal announced March 19, 2026, but uv remains open source under its original permissive license, and the founding Astral team continues developing it as part of OpenAI's Codex division (OpenAI, March 2026).
Q: Can uv run a Python script with no setup at all?
A: Yes, using inline script metadata. A .py file can declare its own dependencies in a # /// script comment block at the top, and uv run script.py builds a throwaway environment matching those declarations, runs the script, and doesn't leave a persistent venv behind — useful for one-off utility scripts you don't want to formalize into a full project.
Q: Does uv replace virtualenv entirely?
A: For most workflows, yes — uv venv creates environments faster than the standard venv module and doesn't require a separate virtualenv install. It uses the same underlying environment format, so tools that expect a standard venv (like most IDEs) work with it unchanged.
Q: What's the single biggest reason to switch from pip to uv today?
A: Time saved in CI. A pipeline that runs pip install on every push and takes 30 to 60 seconds just for dependency installation can drop to a few seconds with uv's cache, and that difference compounds across every commit, every pull request, and every contributor on a team.
The takeaway
uv didn't invent any single new idea in Python packaging — PubGrub resolution, lockfiles, and unified tooling all existed before it in Poetry, PDM, and Rye. What it did was implement all of them in Rust with an obsessive focus on speed and a single consistent interface, and that combination made it fast enough to change daily habits rather than just impress a benchmark chart. The OpenAI acquisition raises legitimate long-term governance questions about who controls foundational Python infrastructure, but the tool itself, its license, and its command set haven't changed. For most new Python projects in 2026, uv is simply the faster default.
Read next:
Follow new articles
Add SciHub101 to your feed reader to see new science and technology stories.
About the Author
SciHub101 is an independent science and technology publication founded and edited by Buğra Sözeri, a software engineer and app developer based in Türkiye. AI tools assist with drafting and research. Source documentation in the existing archive is uneven, and articles are being reviewed and corrected. The Editorial Team byline identifies editorial responsibility; it does not certify specialist or independent human review. Where we compare products, anything built by our own team is labelled as such — see the editorial guidelines and About page for how corrections and disclosures work.
Related Articles

Docker Explained — Containers for Beginners
Learn Docker from scratch: containers vs VMs, Dockerfiles, docker-compose, and how to ship a Node.js app reliably across any environment.

What Is Astro? The Content-First Framework
Astro ships zero JavaScript by default using Islands Architecture. Here's how the content-first framework works and when to pick it over Next.js.

Polars vs Pandas 2026 — Should You Make the Switch?
Polars vs Pandas compared: real benchmarks, syntax differences, migration strategy. Why Polars is often 10 to 20x faster and when switching still isn't worth it.

FastAPI vs Flask vs Django — Python Frameworks
Compare Django, Flask, and FastAPI on speed, features, async support, and use cases. Code examples and a 10-dimension comparison table.

Tauri vs Electron — Desktop App Frameworks
Tauri vs Electron compared: bundle size, performance, security, ecosystem. Which desktop framework should you choose in 2026?

How to Learn Python: A Complete Guide for Beginners in 2026
Python is a sensible first language: readable syntax, a huge library ecosystem, and use in web, data, and automation work. This guide covers setup, a phased learning path, free courses, debugging, learning with AI assistants, and a project ladder.