A review of Python UV

Python, UV, dependency management

Main project image

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 like apt or brew or plain Anaconda. 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, and conda, 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 or pienv 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 using uv pip install ... or uv run ...
  • UV locks dependencies using uv.lock file, similar to package-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 with uv sync and uv run.
  • UV supports both pyproject.toml and requirements.txt files, so you can use it with existing projects without having to change your setup. However, it is preferable to use pyproject.toml as it is the modern standard to specify dependecies or licence details for Python projects. The official pyproject.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 file
  • pyproject.toml file
  • README.md file
  • main.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.