uv, the python package manager

A hipster python package manager with handy features for my workflow

2024-11-18 — 2025-03-17

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, but this is a pure taste thing. The creators recommend

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

1.1 Shell completions

Baseline UV 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.

The following hack 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.

Want to pretend to be running classic venv? 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