uv, the python package manager

A hipster python package manager with handy features for my workflow

November 18, 2024 — March 17, 2025

computers are awful
python
standards
Figure 1

uv is “an extremely fast Python package and project manager, written in Rust.” I would classify it as a pip-like package manager, and moreover, the best package manager for most new projects.

It’s getting strong reviews, e.g. Loopwerk’s one.. Source can be found at astral-sh/uv.

Claimed highlights:

uv is backed by Astral, the creators of Ruff.

Notably, uv has deep, highly specific pytorch support, so if you are doing ML on the GPU, this might be a good choice.

One thing it does not provide is a build back-end; we need to choose one. Who knew that was a thing? I did not know there was a build-front-end/vs build-backend distinction.

1 installation

We can install uv many ways I prefer pipx on Linux and homebrew on macOS. The creators recommend

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

1.1 Shell completions

Shell completions require manual intervention.:

# Determine your shell (e.g., with `echo $SHELL`), then run one of:
echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc
echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc
echo 'uv generate-shell-completion fish | source' >> ~/.config/fish/config.fish

Annoyingly, uv will not autocomplete project entry points, so e.g. uv run will not autocomplete with the list of permissible scripts.

This seems to allow me to get tab-completion for uv run in fish shell. Bash users, let me know if you have a bash solution.

function __fish_uv_run_completions
    set -l uv_output (uv run 2>/dev/null)
    string match -r -- '^\s*- (\w+)' $uv_output | cut -d' ' -f2
end

complete -c uv -n '__fish_seen_subcommand_from run' -a '(__fish_uv_run_completions)'

Add to ~/.config/fish/completions/uv.fish and then source ~/.config/fish/completions/uv.fish.

2 uv project setup

uv requires us to specify a build system in the pyproject.toml file if we want to “install” the package we are currently working on (e.g. do relative imports, have sub-folders in the source tree…). It does not provide one per default. To get one, create the project as one of the following:

uv init --package --build-backend hatch

If the env is already created, we need to add the build system manually into pyproject.toml; some useful ones are included.

Alternatively, we can set tool.uv.package = true in pyproject.toml.

Working on an existing uv system? You are looking for the command:

uv venv --python 3.12 # or other version

uv does not refresh version and download updated dependencies per default. To get that behaviour, we need to use the --upgrade flag:

uv sync --upgrade
run things without installing

uvx

The uvx command invokes a tool without installing it.[…] Tools are installed into temporary, isolated environments when using uvx.

3 Migrating to uv from other systems