A review of Python UV
Coming over from Node.js, I was used to using npm
and yarn
for package management. When I started working with Python, I found the ecosystem a total mess, with multiple tools like: pip
, virtualenv
, pip-tools
, pyenv
and poetry
and multiple different files to keep track of Python dependencies. Most of the problems starting with Python boils down to being “multiple ways to achieve a single solution”.
Recently, I came across a new tool called UV that aims to simplify Python dependency management. Compared to the existing tools, it has a lot of promise on solving the problems with Python such as:
- There are different ways to install Python. You can download the official Python installer, use
pyenv
, or use a package manager likeapt
orbrew
or plainAnaconda
. Its a massive point of friction. - Python is used for everything from web development to data sciecne, so its difficult to create one guide for every use case.
- There are multiple ways to manage Python dependencies, such as
pip
,pipenv
,poetry
, andconda
, which can lead to confusion and inconsistency. - Having to add
PATH
system variables to Windows / Linux to get it working. - Messy compiled extensions and libraries.
- Dealing with multple Python versions installed on the same machine.
- When using
pip
, you have to manually create and activate virtual environments, which can be cumbersome and error-prone. Additionally,pip
does not lock dependencies, which can lead to inconsistent environments across different machines.
UV is a dependency management tool that focuses on simplicity and ease of use. It allows you to manage your Python dependencies in a straightforward way, without the complexity of some of the other tools in the ecosystem.
Some of the the key features and pros:
- UV is written in Rust, so its faster than
pip
orpienv
when creating environments and resolving dependencies. - UV can create and manage virtual environments without specifically calling
python -m venv
. - UV works as a replacement for
pip
commands usinguv pip install ...
oruv run ...
- UV locks dependencies using
uv.lock
file, similar topackage-lock.json
in Node.js, which is the universal or cross-platform way to manage dependencies to ensure consistent and reproducible installations across computers - which is by far the most common error encountered by Python developers. This lockfile is automatically created and updated withuv sync
and uvrun
. - UV supports both
pyproject.toml
andrequirements.txt
files, so you can use it with existing projects without having to change your setup. However, it is preferable to usepyproject.toml
as it is the modern standard to specify dependecies or licence details for Python projects. The officialpyproject.toml
specs are here uv remove
command to remove dependencies from the project.uv run
will run any command in the virtual environment, so you don’t have to worry about activating the environment first (woohoo!).
Initial setup
UV also makes it super easy to get a project setup. You can initiate a new Python UV project using the command:
uv init hello-world
This will create a new directory called hello-world
with a basic project structure, including a pyproject.toml
file. You can then navigate into the directory and start adding dependencies. This proejct structure includes:
.gitignore
filepyproject.toml
fileREADME.md
filemain.py
file.python-version
file: this contains the prject’s default Python version for the virtual environment.uv.lock
file: this contains the exact resolved versions installed in the project environment..venv
directory: this is the virtual environment created by UV.
Dependencies can be added to the pyproject.toml
with the command:
uv add ...
This will automatically update the uv.lock
file with the exact versions of the dependencies installed. For example, to add requests
, you can run:
uv add requests
uv run .... # locking and syncing happens automatically before invoking the command
You can also use the uv run
command to run Python commands in the virtual environment at .venv
without having to run source venv/bin/activate
beforehand. For example, python -c "import requests"
can only be run like this:
uv run python -c "import requests"
Would I recommend UV?
Yep, UV feels quick and responsive compared to pip
and venv
, especially when creating new environments or installing dependencies. I will definitely be using it for my next/future Python projects and explore it further.