An ode to uv

Kenny Chou · January 16, 2025

After using uv for a couple months, it continues to impress. It’s fast. It’s easy to use. I have not completely abandoned Poetry because my existing projects are already configered to use Poetry, and my colleagues have not yet adopted uv. Nonetheless, uv still offers tremendous advantages in my workflow. This post will explain how I make use of uv in my workflows and its advnatages over other tools, when my projects are still configured for Poetry.

Installation

First, install uv. There are many ways to install uv. I prefer to use one of these methods:

# Standalone installer 
curl -LsSf https://astral.sh/uv/install.sh | sh

# pipx
pipx install uv

# brew
brew install uv

Advanced settings for linux servers

If you’re working on linux servers, you may have do adjust some settings due to the limited amount of disk space available in the home directory.

Add the following to your .bashrc

export UV_PYTHON_INSTALL_DIR=my_python_install_dir

See additional settings for uv in the docs.

By default, uv will also utilize your ~/.cache directory. So I recommend creating a symlink to a directory that’s not space-restricted.

ln -s my_unrestricted_dir/.cache ~/.cache

! If you run into invalid peer certificate: UnknownIssuer solution issues, run export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt in console then try again. (source)

Python Management

uv replaces pyenv

You don’t have to explicitly install python versions, since uv will download any missing python versions for you. But sometimes, it’s good to be explicit.

# Install one or more python versions
uv python install 3.11 3.12

# View python installations
uv python list

Python binaries managed by uv lives in a specific directory. You can control where Python interpreters are installed using the UV_PYTHON_INSTALL_DIR environment variable. See other fine-grained control you have in the docs.

Environment management

uv replaces virtualenv

# explicitly set up an environment.
uv venv <path/myenv> --python 3.11

source <path/myenv>/bin/activate

Why use uv for environment management? Primarily because it can also act as a Python version manager. It quickly downloads python interpreters if they aren’t found on your system. I’ve compared uv with other common environment managers here.

Install packages

uv replaces pip

uv is much faster than pip and poetry. Can we use it to install a Poetry-managed project? Absolutely, yes!

In my workflow, I generate requirement.txt files because it doesn’t make sense to include poetry in production. This is done automatically with poetry-auto-export. With poetry-auto-export installed, new requirement files are generated every time poetry.lock file is updated.

Since uv is a drop-in replacement for pip, we can call

# install your dependencies
uv pip install -r requirements.txt

# install the current project
uv pip install . --no-deps

If you don’t have poetry-auto-export, you can manually export the requirement files (or write a script that does it for you).

In situations where you have to install packages over and over again, uv can significantly speed up your workflow. Such as…

  • Running tests with nox/tox. In these situations, packages are installed in fresh environments, which are destroyed after the test finishes.
  • During CI workflows – see Using uv in Github Actions. Use uv to install both Python and your requirements!

Update: May 2025

If your projects have been configured for Poetry versions 2.x and higher and your dependencies are specified in the [project] table of your pyproject.toml, then you can directly call uv sync to install your dependencies.

Summary

These are by no means the full extent of uv’s capabilities. It replaces pipx. It handles monorepos much better than Poetry via workspaces. It can manage entire projects, build and publish packages. I haven’t yet used uv for these tasks, but I’ll update this post once I do.

Further reading