uv package manager

published: August 3, 2025

overview

uv - fast python package and project manager written in rust

  • created by astral
  • astral also makes ruff and ty
  • uv, uvx, ruff, and ty are all generally well integrated with each other
  • uv and maturin (PyO3) are also well integrated
  • official docs

llm compatibility warning

most llms lack knowledge of uv due to training data cutoffs. uv’s first gh release was in february 2024, and most pretrain content like blog posts, how to guides, and textbooks still leans heavily towards poetry or conda solutions.

when using llms:

  • explicitly specify uv usage, e.g., in CLAUDE.md
  • provide command examples, especially for uv pip and uv add
  • link to uv documentation
  • correct legacy tool suggestions

use cases

  1. python - manage python versions like in the setup guide
  2. projects - applications with dependencies, just like you’d have used poetry
  3. environments - virtual environments like you’d have used virtualenv or conda
  4. scripts - single files with inline dependencies
  5. tools - cli utilities via uvx like ruff, mypy, ty, etc.

cache

location: ~/.cache/uv/

# manage cache
uv cache clean          # clear all
uv cache prune         # remove unused
uv cache clean pandas  # clear specific package

cache features:

  • atomic operations
  • thread-safe
  • hard-linked files

project management

initialization

uv init my-project
cd my-project

# creates:
# pyproject.toml
# .python-version
# README.md
# .gitignore

dependencies

# add packages
uv add httpx
uv add "polars>=2.0"
uv add git+https://github.com/repo/name

# dev dependencies
uv add --group dev pytest

# optional groups
uv add --optional notebooks jupyter

lock file

# update all
uv lock --upgrade

# update specific
uv lock --upgrade-package pandas

# sync from lock
uv sync

workspaces

# root pyproject.toml
[tool.uv.workspace]
members = ["packages/*", "apps/*"]
uv sync                    # install all
uv run --workspace pytest  # run in all

scripts

inline dependencies

#!/usr/bin/env -S uv run
# /// script
# dependencies = [
#   "httpx",
#   "rich",
# ]
# requires-python = ">=3.12"
# ///

import httpx
from rich import print

response = httpx.get("https://api.github.com")
print(response.json())

adding dependencies

uv add --script script.py requests rich

tools (uvx)

ephemeral execution

# run tools
uvx ruff check .
uvx ty check .
uvx pytest

# specific version
uvx ruff@0.5.0 check .

# from git
uvx --from git+https://github.com/tool/name tool-name

# with extras
uvx --from 'mypy[faster-cache]' mypy

permanent installation

# install
uv tool install ruff
uv tool install 'mypy[faster-cache,reports]'

# manage
uv tool list
uv tool upgrade ruff
uv tool upgrade --all
uv tool uninstall ruff

python management

# install versions
uv python install 3.13
uv python install 3.12
uv python install pypy@3.10

# list
uv python list           # available
uv python list --installed

# pin version
uv python pin 3.13

# run with version
uv run --python 3.12 python script.py

uses python-build-standalone distributions.

docker integration

using pre-built python image

FROM ghcr.io/astral-sh/uv:latest as uv
FROM python:3.13-slim

COPY --from=uv /uv /uvx /bin/

RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project

COPY . .

RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen

CMD ["uv", "run", "python", "-m", "myapp"]

using minimal base with uv-installed python

FROM ghcr.io/astral-sh/uv:latest as uv
FROM ubuntu:22.04

# minimal deps for uv
RUN apt-get update && apt-get install -y \
    curl \
    ca-certificates \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# copy uv
COPY --from=uv /uv /uvx /bin/

# install python using uv
RUN uv python install 3.13

WORKDIR /app
COPY pyproject.toml uv.lock ./

RUN --mount=type=cache,target=/root/.cache/uv \
    UV_LINK_MODE=copy \
    uv sync --frozen --no-install-project

COPY . .
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen

CMD ["uv", "run", "python", "-m", "myapp"]

docker tips

  • use --frozen for reproducibility
  • use --no-install-project to cache dependencies
  • set UV_LINK_MODE=copy with cache mounts
  • use --compile-bytecode for faster startup

environment variables

UV_CACHE_DIR=/path/to/cache     # cache location
UV_TOOL_DIR=/path/to/tools      # tools location
UV_LINK_MODE=copy              # force copy mode
UV_NO_CACHE=1                  # disable cache
UV_INDEX_URL=https://url       # custom index

advanced features

custom indexes

[[tool.uv.index]]
name = "internal"
url = "https://internal.pypi.company.com/simple"

[tool.uv.sources]
my-package = { index = "internal" }

build backend

[build-system]
requires = ["uv>=0.8.0"]
build-backend = "uv.build"

limitations: pure python only

platform-specific dependencies

[tool.uv.sources]
torch = [
    { index = "pytorch-cpu", markers = "platform_system == 'Linux'" },
    { index = "pytorch-cuda", markers = "platform_system == 'Windows'" },
]

pre-releases

uv add "numpy>=2.0.0rc1" --prerelease=allow
uv sync --prerelease=allow

common workflows

development setup

git clone https://github.com/repo/project
cd project
uv sync --group dev
uv run pytest
uvx ruff check .

ci optimization

uv sync --frozen
uv cache prune --ci

jupyter

# temporary
uv run --with jupyter --with pandas --with matplotlib jupyter lab

# permanent
uv add --group notebooks jupyter pandas matplotlib
uv run jupyter lab

tips

  1. always use .python-version
echo "3.13" > .python-version
  1. inline scripts for one-offs
uv init --script analyze.py --python 3.13
uv add --script analyze.py pandas matplotlib
  1. standard toolkit
uv tool install ruff mypy ipython httpie
  1. workspace commands
uv sync
uv run -m packages.myapp
uv run --workspace pytest

troubleshooting

reset

rm -rf ~/.cache/uv
rm -rf ~/.local/share/uv
curl -LsSf https://astral.sh/uv/install.sh | sh

debug

uv tree           # dependency tree
uv -v sync       # verbose
uv -vvv sync     # very verbose

network

uv sync --index-url https://pypi.org/simple
uv sync --trusted-host pypi.org

resources

══════════════════════════════════════════════════════════════════
on this page