UV: A powerful, reliable and retro-compatible package manager for Python
Jordão Rosario
July 22, 2025
•
5 min read
Until recently, the Python development community lacked a unified tool that matched the capabilities of package managers like npm
and yarn
in JavaScript or cargo
in Rust. Setting up a new Python project was cumbersome, requiring multiple tools and configurations to handle dependencies, version management, and environment setup.
Traditional workflows also tend to be slow, especially when reinstalling dependencies from scratch.
For many Python projects, especially those using pip and requirements.txt, the lack of a standardized lockfile
is a major challenge. Without a lockfile
, it becomes difficult to pin exact dependency versions, making it hard to reliably recreate or maintain environments across machines and points in time. While tools like Poetry and Pipenv introduced their own lockfile
solutions, these remain fragmented and are not consistently adopted across the ecosystem.
Enter uv
: a powerful, reliable, and retro-compatible package manager for Python that aims to solve all of these issues in one streamlined tool.
Installation
https://docs.astral.sh/uv/#installation
A Powerful and Reliable Tool
UV is capable of replacing :
pip
pip-tools
pipx
poetry
pyenv
twine
virtualenv
How do we use it? Let's start by setting up a new project:
uv init uv_presentation
cd uv_presentation
uv will create the following files:
├── .gitignore
├── .python-version
├── README.md
├── main.py
└── pyproject.toml
The main.py file contains a simple "Hello world" program. Try it out with uv run
:
uv run main.py
Managing Dependencies
You can easily add, upgrade or remove dependencies without having to manually modify your dependencies file, with some simple commands: If you want to add:
uv add pandas
You can also specify version constraints or alternative sources:
# Specify a version constraint
uv add 'requests==2.31.0'
# Add a git dependency
uv add git+https://github.com/psf/requests
or if you want to remove it:
uv remove pandas
And if you want to upgrade it:
uv lock --upgrade-package requests
Just how powerful is UV—and does it really live up to the claim of being retro compatible?
Let's say that you have an old project that in python that was using pip tools to install the necessary dependencies of it, such as:
requirements.txt
fastapi
uvicorn[standard]
pandas
numpy
scikit-learn
requests
pydantic
sqlalchemy
matplotlib
And let's say the project specifies that it uses Python version 3.12
. In that case, you would typically need to:
- install that specific python version or use something such as
pyenv
to manage the specific python at it - create the virtual environment manually on the folder
- activate the virtual env
- install your dependencies using pip
You would need to run the below commands to set everything up:
pyenv install 3.12
pyenv global 3.12
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
And not only that, you would need to wait a little bit to install every depedency on it, and we can measure how much time it would take, so let's do it:
python3 -m venv pip_venv
source pip_venv/bin/activate
echo "timing: pip install"
pip_time=$(TIMEFORMAT=%R; { time python3 -m pip install -r requirements.txt --no-cache-dir >/dev/null 2>&1; } 2>&1)
echo "pip install time: ${pip_time}s"
deactivate
rm -rf pip_venv
It took an average of 21 seconds to install all dependencies. So, can uv
simplify this process? Absolutely. Let's use the same "requirements" and translate it to work with uv
:
uv venv --python 3.12 # Yes, this creates a venv and also install the specified python version
source .venv/bin/activate
uv pip install -r requirements.xt # and we can use the same api as pip
But we want to measure how much time it would take to install the dependencies with uv
, so let's create a similar script to do this:
uv venv --python 3.12 # Yes, this creates a venv and also install the specified python version
source .venv/bin/activate
echo "timing: uv install"
uv_time=$(TIMEFORMAT=%R; { time uv pip install -r requirements.txt --no-cache-dir >/dev/null 2>&1; } 2>&1)
echo "uv install time: ${uv_time}s"
deactivate
rm -rf .venv
This process takes less than 4 seconds to complete.
UV isn't just fast—it also simplifies migrating existing projects. If you have an older project with a requirements.txt
and some constraints in a constraints.txt
, you can migrate it with:
cd {folder_of_project_with_requirements}
uv init
uv add -r requirements.txt -c constraints.txt
And that's it, when you would like to set up your project on a different environment you will only need to
uv sync
source .venv/bin/activate
This will automatically install the specified python version on the .python-version file and install of the dependencies for your project.
Highlights
As shared by the uv
team:
- 🚀 A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
- ⚡️ 10-100x faster than pip.
- 🗂️ Provides comprehensive project management, with a universal lockfile.
- ❁️ Runs scripts, with support for inline dependency metadata.
- 🐍 Installs and manages Python versions.
- 🛠️ Runs and installs tools published as Python packages.
- 🔩 Includes a pip-compatible interface for a performance boost with a familiar CLI.
- 🏢 Supports Cargo-style workspaces for scalable projects.
- 💾 Disk-space efficient, with a global cache for dependency deduplication.
- ⬇️ Installable without Rust or Python via curl or pip.
- 🖥️ Supports macOS, Linux, and Windows.
To learn more
SHARE THIS STORY
Get in touch
Whether your plans are big or small, together, we'll get it done.
Let's get a conversation going. Shoot an email over to projects@betaacid.co, or do things the old fashioned way and fill out the handy dandy form below.