uv#

uv isn't "faster pip." it's cargo for python - a unified toolchain that changes what's practical to do.

install#

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

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

the commands you actually use#

uv sync          # install deps from pyproject.toml
uv run pytest    # run in project environment
uv add httpx     # add a dependency
uvx ruff check   # run a tool without installing it

never use uv pip. that's the escape hatch, not the workflow.

zero-setup environments#

run tools without installing anything:

uvx flask --help
uvx ruff check .
uvx pytest

this creates an ephemeral environment, runs the tool, done. no virtualenv activation, no pip install.

the repro pattern#

testing specific versions without polluting your environment:

# test against a specific version
uv run --with 'pydantic==2.11.4' repro.py

# test a git branch before it's released
uv run --with pydantic@git+https://github.com/pydantic/pydantic.git@fix-branch repro.py

# combine: released package + unreleased fix
uv run --with prefect==3.1.3 --with pydantic@git+https://github.com/pydantic/pydantic.git@fix repro.py

for monorepos with subdirectories:

uv run --with git+https://github.com/prefecthq/prefect.git@branch#subdirectory=src/integrations/prefect-redis repro.py

inline script metadata#

PEP 723 lets you embed dependencies directly in a script:

# /// script
# dependencies = ["httpx", "rich"]
# requires-python = ">=3.12"
# ///

import httpx
from rich import print

print(httpx.get("https://httpbin.org/get").json())

run with uv run script.py - uv reads the metadata and creates an environment with those dependencies. no pyproject.toml, no requirements.txt, just a self-contained script.

this is how you share reproducible examples. put the dependencies in the file itself, and anyone with uv can run it.

shareable one-liners#

no file needed:

uv run --with 'httpx==0.27.0' python -c 'import httpx; print(httpx.get("https://httpbin.org/get").json())'

share in github issues, slack, anywhere. anyone with uv can run it.

stdin execution#

pipe code directly:

echo 'import sys; print(sys.version)' | uv run -
pbpaste | uv run --with pandas -

project workflow#

uv init myproject        # create new project
cd myproject
uv add httpx pydantic    # add deps
uv sync                  # install everything
uv run python main.py    # run in environment

uv sync reads pyproject.toml and uv.lock, installs exactly what's specified.

why this matters#

the old way:

  1. install python (which version?)
  2. create virtualenv
  3. activate it (did you remember?)
  4. pip install (hope versions resolve)
  5. run your code

the uv way:

  1. uv run your_code.py

uv handles python versions, environments, and dependencies implicitly. you stop thinking about environment management.

sources: