Skip to content

12 - uv

Quick reference for uv: a very fast tool that manages Python versions, virtual environments, dependencies and CLI tools in one (replaces pip, venv, pip-tools, pipx and pyenv).

Last verified: 2026-09-27. For newer changes, check the Official docs links in the Introduction.

Introduction

Before you start

You should know: what packages, dependencies, versions and lock files are (01 - Core Concepts section 5), and why projects need their own environment (11 - Virtual Environments).

The problem it solves: a Python project needs four things to be exactly right on every machine: the Python version, an isolated environment, the packages, and their exact versions. Get any one wrong and the project that works on your laptop fails on a colleague's machine, in CI or in Docker ("it works on my machine").

Before uv: each of those jobs had its own tool, with its own commands and config: pyenv (Python versions), venv (environments), pip (installing), pip-tools or pip freeze (pinning versions), pipx (command-line tools). Beginners had to learn all five and often mixed them up; pip was also slow on big projects. Poetry and PDM combined some of these jobs; uv (2024) combines all of them and is much faster.

Think of it like: one assistant who reads your project's shopping list (pyproject.toml), buys exactly the same brands every time (uv.lock), and packs a separate, identical toolbox (.venv) for the project on every machine, in seconds.

What is uv?

uv is a modern, extremely fast Python package and project manager, written in Rust by Astral (the company behind the Ruff linter). It replaces a whole set of separate tools with one command:

Job Tool you needed before With uv
Install packages pip uv add / uv pip install
Create virtual environments venv / virtualenv automatic, or uv venv
Pin exact versions pip freeze, pip-tools uv.lock (automatic)
Install Python versions python.org installer, pyenv uv python install
Run CLI tools in isolation pipx uvx / uv tool install
Build and publish packages build, twine, poetry uv build, uv publish

In short: you describe what your project needs in pyproject.toml, and uv makes sure the right Python version, the right environment and the exact right package versions exist, every time, on every machine.

How does it work?

  1. pyproject.toml lists your direct dependencies (for example "pandas >= 2.2").
  2. Resolving: uv works out a compatible version for every package and every sub-dependency.
  3. uv.lock records those exact versions (the lock file), so everyone gets identical installs.
  4. .venv is created and synced to match the lock file automatically.
  5. Global cache: each package version is downloaded once and linked into all your projects, so new environments are created in seconds and use little disk space.

Why use it?

  • Very fast: installs are often 10 to 100 times faster than pip; creating a new environment takes seconds.
  • One tool instead of five: Python versions, environments, packages, locking and tools in one place.
  • Reproducible: uv.lock guarantees the same versions on your laptop, a colleague's laptop, CI and Docker.
  • No activation needed: uv run app.py always uses the right environment.
  • Manages Python itself: need Python 3.12 for one project and 3.11 for another? uv installs and switches automatically.
  • Standard files: uses the official pyproject.toml format, so other tools understand the project.
  • Easy to adopt: uv pip ... works like pip, so existing requirements.txt projects work unchanged.

When to use uv (and when not)

Use uv Consider something else
New Python projects (apps, APIs, data projects) You need non-Python system libraries (CUDA toolkits, GDAL, R): conda may be easier
You want fast, repeatable installs in CI / Docker A team or platform requires a specific tool (Poetry, conda)
You juggle several Python versions Tiny one-off script with no dependencies: plain python is enough

Key terms

Term Meaning
Dependency A package your project needs (pandas, fastapi)
Transitive dependency A package your dependencies need (numpy for pandas)
pyproject.toml Project file: name, Python version, dependencies, tool settings
uv.lock Exact versions of every package; commit it to Git
.python-version Which Python version this project uses
Resolve Work out a set of versions that are compatible with each other
Sync Make .venv match the lock file exactly
Dependency group Extra packages only for some uses, e.g. dev (pytest, ruff)
Tool A command-line program (ruff, black) installed separately from projects

Where it fits: replaces the steps in 11 - Python Virtual Environment; works with 06 - VS Code, 16 - Jupyter and 43 - Docker.

Official docs

Where to read the latest, authoritative documentation:

Resource Link
uv documentation https://docs.astral.sh/uv/
uv on GitHub (releases, issues) https://github.com/astral-sh/uv
Writing pyproject.toml https://packaging.python.org/en/latest/guides/writing-pyproject-toml/

Contents

  1. Flags and Parameters
  2. What uv Is and Why
  3. Install and Update
  4. Two Ways to Use uv
  5. Create a Project
  6. Add and Remove Dependencies
  7. Run Code
  8. Lock and Sync
  9. pyproject.toml
  10. Dependency Groups (dev, test)
  11. Manage Python Versions
  12. pip-Compatible Interface
  13. requirements.txt Import and Export
  14. Tools (uvx)
  15. Single-File Scripts
  16. Migrate from venv + pip
  17. uv in VS Code and Jupyter
  18. uv in Docker
  19. uv vs venv + pip vs conda
  20. Troubleshooting
  21. Try It

0. Flags and Parameters

The meaning of the uv sub-commands and flags used below. uv <command> [flags] [arguments]; uv <command> --help lists everything.

Use this when you see uv add --dev pytest or uv sync --frozen --no-dev and want to know what each part does.

uv  add  --dev  pytest
|   |    |      |
|   |    |      +-- package to add
|   |    +--------- flag: put it in the "dev" group (not needed in production)
|   +-------------- sub-command: add a dependency to pyproject.toml and install it
+------------------ program
Command Flag Meaning
uv init --app / --lib / --package Project type: application (default), library, installable package
uv init --python 3.12 Python version for the project
uv add --dev Add to the dev dependency group
uv add --group test Add to a named group
uv add -r requirements.txt Add every package from a requirements file
uv add / uv remove --script file.py Change the inline dependencies of a single script
uv run --with pkg Add a package just for this run
uv run --python 3.11 Run with another Python version
uv sync --frozen Use uv.lock as-is, do not update it
uv sync --locked Fail if uv.lock is out of date (good for CI)
uv sync --no-dev Skip dev dependencies (production)
uv sync --all-groups Install every dependency group
uv lock --upgrade Upgrade all packages to the newest allowed versions
uv lock --upgrade-package pandas Upgrade only this package
uv venv --python 3.12 Create the venv with this Python
uv pip compile -o requirements.txt Output file for the pinned list
uv export --format requirements-txt Export the lock file as requirements.txt
uv export --no-hashes Leave out hashes (shorter file)
uv tree --depth 1 Only direct dependencies
uv tool upgrade --all Upgrade every installed tool

1. What uv Is and Why

One fast tool (written in Rust by Astral, the makers of Ruff) for the whole Python workflow. Reads pyproject.toml, creates .venv automatically, pins exact versions in uv.lock, caches downloads globally.

Use it for new projects where you want fast installs, reproducible environments and one tool instead of five.

Task Old way uv way
Install Python python.org / pyenv uv python install 3.12
Create venv python -m venv .venv automatic (or uv venv)
Install package pip install pandas uv add pandas
Pin versions pip freeze > requirements.txt uv.lock (automatic)
Recreate env pip install -r requirements.txt uv sync
Run script activate, then python app.py uv run app.py
CLI tools pipx install ruff uv tool install ruff / uvx ruff

Installs are typically 10 to 100 times faster than pip.

2. Install and Update

Getting the uv command on your machine. Standalone installer (no Python needed), winget, or pip.

Use it once per machine.

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
winget install --id=astral-sh.uv -e             # alternative
# Mac / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
pip install uv                  # alternative (inside any Python)
uv --version
uv self update                  # update uv (standalone install only)

Open a new terminal after installing so uv is on PATH.

3. Two Ways to Use uv

uv has a project mode and a pip-compatible mode. Project mode uses pyproject.toml + uv.lock; pip mode mirrors familiar pip / venv commands.

Use it for project mode for new work (recommended); pip mode to speed up existing requirements.txt projects without changing them.

Project mode (recommended) pip-compatible mode
uv init, uv add, uv run, uv sync uv venv, uv pip install, uv pip freeze
Dependencies in pyproject.toml Dependencies in requirements.txt
Exact versions in uv.lock Pin with uv pip compile
No need to activate the venv Activate .venv as usual

4. Create a Project

Starting a new project with uv. uv init creates pyproject.toml, .python-version, main.py, README.md and a Git repo.

Use it in every new Python project.

uv init my-project                  # new folder
cd my-project
uv init                             # or: inside an existing folder
uv init --python 3.12               # choose Python version
uv init --package my-lib            # installable package with src/ layout
my-project/
  .python-version     Python version for this project
  pyproject.toml      project info and dependencies
  main.py             starter file
  README.md
  .venv/              created on first uv add / uv run / uv sync
  uv.lock             exact versions (commit this!)

5. Add and Remove Dependencies

Installing and uninstalling packages for the project. uv add updates pyproject.toml, uv.lock and .venv in one step.

Use this when whenever the project needs a new library (instead of pip install).

uv add pandas                       # latest compatible version
uv add "pandas>=2.2"                # with version constraint
uv add pandas numpy matplotlib      # several at once
uv add "fastapi[standard]"          # with extras
uv add --dev pytest ruff            # development only
uv add git+https://github.com/user/repo    # from Git
uv add ./libs/mylib --editable      # local package, live changes
uv remove matplotlib                # uninstall and remove from pyproject.toml
uv tree                             # dependency tree
uv pip list                         # installed packages in .venv

6. Run Code

Running Python, scripts and tools inside the project environment. uv run makes sure .venv is up to date with the lock file, then runs the command in it.

Use it always, instead of activating the venv (activation still works if you prefer it).

uv run main.py                      # run a script
uv run python                       # interactive Python in the project env
uv run -m pytest                    # run a module
uv run pytest -q                    # run a tool installed in the project
uv run uvicorn app.main:app --reload
uv run --with rich main.py          # temporarily add a package
uv run --python 3.11 main.py        # try another Python version

Prefer to activate? .venv\Scripts\activate (Windows) or source .venv/bin/activate, then use python as usual.

7. Lock and Sync

uv.lock records the exact version of every package; sync makes .venv match it. uv add / uv remove update the lock automatically; uv sync installs / removes to match.

Use it after cloning a project, after git pull, in CI and in Docker builds.

uv sync                             # make .venv match uv.lock (after clone / pull)
uv sync --no-dev                    # without dev dependencies (production)
uv sync --locked                    # CI: fail if the lock is out of date
uv sync --frozen                    # Docker: trust the lock, do not check pyproject
uv lock                             # re-create the lock without installing
uv lock --upgrade                   # upgrade everything within constraints
uv lock --upgrade-package pandas    # upgrade one package

Commit pyproject.toml, uv.lock and .python-version. Do not commit .venv/.

8. pyproject.toml

The standard Python project file: name, Python version, dependencies, tool settings. uv edits it for you; you can also edit it by hand, then run uv sync.

Use it for checking or changing dependencies, adding tool config (Ruff, pytest).

[project]
name = "sales-api"
version = "0.1.0"
description = "API that serves sales forecasts"
requires-python = ">=3.12"
dependencies = [
    "fastapi[standard]>=0.115",
    "pandas>=2.2",
    "scikit-learn>=1.5",
]

[dependency-groups]
dev = ["pytest>=8", "ruff>=0.6"]

[tool.ruff]
line-length = 100

9. Dependency Groups (dev, test)

Packages needed only for development, tests or docs. Stored under [dependency-groups]; dev is installed by default, others on request.

Use it for keep pytest, ruff, jupyter out of production images.

uv add --dev pytest ruff            # dev group
uv add --group notebook jupyterlab  # custom group
uv sync --group notebook            # include a custom group
uv sync --all-groups                # include every group
uv sync --no-dev                    # production install

10. Manage Python Versions

Installing and switching Python versions without python.org installers. uv downloads standalone Python builds into its own folder; .python-version pins one per project.

Use this when a project needs a specific Python, or you want to test on several versions.

uv python list                      # available and installed versions
uv python install 3.12              # install
uv python install 3.11 3.13         # several
uv python pin 3.12                  # write .python-version for this project
uv python find                      # path of the Python uv would use
uv python uninstall 3.11

uv also installs the right Python automatically when a project needs it.

11. pip-Compatible Interface

Drop-in faster replacements for venv and pip commands. Same ideas and flags as pip, prefixed with uv.

Use it for existing projects based on requirements.txt that you do not want to convert.

uv venv                             # create .venv
uv venv --python 3.12               # with a specific Python
.venv\Scripts\activate              # Windows (Mac/Linux: source .venv/bin/activate)
uv pip install pandas               # install into the active / local .venv
uv pip install -r requirements.txt
uv pip uninstall pandas
uv pip list
uv pip freeze > requirements.txt
uv pip compile requirements.in -o requirements.txt    # pin versions from loose list
uv pip sync requirements.txt        # make env EXACTLY match the file (removes extras)

12. requirements.txt Import and Export

Moving between requirements.txt and uv projects. uv add -r imports a list; uv export writes the lock as a requirements file.

Use it for converting an old project, or a platform / teammate that only understands requirements.txt.

uv add -r requirements.txt                          # import into pyproject.toml
uv export --format requirements-txt --no-hashes > requirements.txt   # export pinned list

13. Tools (uvx)

Running or installing command-line tools written in Python, isolated from your projects. uvx runs a tool in a temporary cached env; uv tool install keeps it on PATH.

Use it for tools you use everywhere (ruff, black, httpie, jupyter) without adding them to each project.

uvx ruff check .                    # run without installing (same as: uv tool run ruff)
uvx pycowsay "hello"
uvx --from jupyterlab jupyter lab   # package name differs from command name
uv tool install ruff                # install permanently
uv tool list
uv tool upgrade --all
uv tool uninstall ruff

14. Single-File Scripts

Scripts that declare their own dependencies at the top of the file. uv add --script writes an inline metadata block; uv run creates a temporary env for it.

Use it for small utility scripts you share or run occasionally, with no project folder.

uv init --script fetch.py --python 3.12
uv add --script fetch.py requests rich
uv run fetch.py
# /// script
# requires-python = ">=3.12"
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print

print(requests.get("https://api.github.com").status_code)

15. Migrate from venv + pip

Moving an existing project to uv project mode. Initialise uv in the folder, import the requirements, delete the old venv.

Use it when you want uv's speed and lock file for an existing project.

cd my-old-project
uv init                             # adds pyproject.toml (keeps your files)
uv add -r requirements.txt          # import dependencies
Remove-Item -Recurse -Force venv    # remove old env if named differently (Bash: rm -rf venv)
uv sync                             # create .venv from the lock
uv run python main.py               # check it works

16. uv in VS Code and Jupyter

Using the uv-created .venv in the editor and notebooks. uv makes a normal .venv folder, so VS Code and Jupyter can use it like any venv.

Use it in every uv project you open in VS Code or notebooks.

uv add --dev ipykernel              # needed for notebooks
uv run --with jupyter jupyter lab   # start Jupyter with the project env

VS Code: Ctrl+Shift+P -> Python: Select Interpreter -> .venv. See 06 - VS Code and 16 - Jupyter.

17. uv in Docker

Fast, reproducible installs in container builds. Copy the uv binary from its official image, install from the lock file, then copy code.

Use it for dockerising a uv project. See 43 - Docker.

FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app

# Install dependencies first so this layer is cached when only code changes
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project

COPY . .
RUN uv sync --frozen --no-dev

ENV PATH="/app/.venv/bin:$PATH"
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Add .venv to .dockerignore.

18. uv vs venv + pip vs conda

Which environment tool to pick. Compare what each manages and where it shines.

Use it for starting a project or joining a team with an existing setup.

venv + pip uv conda
Speed Slow Very fast Slow to medium
Installs Python itself No Yes Yes
Lock file No (freeze by hand) Yes (uv.lock) Via extra tools
Non-Python packages (CUDA, GDAL, R) No No Yes
Standard files requirements.txt pyproject.toml environment.yml
Best for Simple scripts, legacy projects Most new Python projects Heavy scientific / GPU stacks with system libraries

19. Troubleshooting

Problem Fix
uv not recognized Open a new terminal; check the installer added %USERPROFILE%\.local\bin to PATH
Installer script blocked Use the exact -ExecutionPolicy ByPass command in section 2, or winget
No solution found when resolving dependencies Version constraints conflict; loosen one (uv add "pkg>=1") or check requires-python
The lockfile needs to be updated in CI Run uv lock locally and commit uv.lock
VS Code uses the wrong Python Select .venv as interpreter; run uv sync first so it exists
ModuleNotFoundError with plain python Use uv run python ... or activate .venv
Package installed with uv pip install disappears after uv sync sync matches the lock; use uv add in project mode
Want a clean start Delete .venv, then uv sync
Cache uses too much disk uv cache clean (or uv cache prune)

20. Try It

Short exercises to practise this guide. Try each task yourself first, then open the solution.

Use it right after reading the guide, or later as a quick self-test.

Exercise 1: New project

Create a uv project, add pandas, add pytest as a dev dependency and run a script.

Solution
uv init sales && cd sales
uv add pandas
uv add --dev pytest
uv run main.py

Exercise 2: Upgrade one package

Upgrade only pandas in the lock file and environment.

Solution
uv lock --upgrade-package pandas
uv sync

Exercise 3: Tool without installing

Lint the project with Ruff without adding it to the project, then export a requirements.txt.

Solution
uvx ruff check .
uv export --format requirements-txt --no-hashes > requirements.txt