12 - uv¶
Previous: 11 - Python Virtual Environment | Index: All guides | Next: 13 - Pydantic
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?¶
pyproject.tomllists your direct dependencies (for example "pandas >= 2.2").- Resolving: uv works out a compatible version for every package and every sub-dependency.
uv.lockrecords those exact versions (the lock file), so everyone gets identical installs..venvis created and synced to match the lock file automatically.- 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.lockguarantees the same versions on your laptop, a colleague's laptop, CI and Docker. - No activation needed:
uv run app.pyalways 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.tomlformat, so other tools understand the project. - Easy to adopt:
uv pip ...works like pip, so existingrequirements.txtprojects 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¶
- Flags and Parameters
- What uv Is and Why
- Install and Update
- Two Ways to Use uv
- Create a Project
- Add and Remove Dependencies
- Run Code
- Lock and Sync
- pyproject.toml
- Dependency Groups (dev, test)
- Manage Python Versions
- pip-Compatible Interface
- requirements.txt Import and Export
- Tools (uvx)
- Single-File Scripts
- Migrate from venv + pip
- uv in VS Code and Jupyter
- uv in Docker
- uv vs venv + pip vs conda
- Troubleshooting
- Try It
0. Flags and Parameters¶
The meaning of the uv sub-commands and flags used below.
uv <command> [flags] [arguments];uv <command> --helplists everything.Use this when you see
uv add --dev pytestoruv sync --frozen --no-devand 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.venvautomatically, pins exact versions inuv.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
uvcommand 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
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 familiarpip/venvcommands.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 initcreatespyproject.toml,.python-version,main.py,README.mdand 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 addupdatespyproject.toml,uv.lockand.venvin 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 runmakes sure.venvis 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.lockrecords the exact version of every package;syncmakes.venvmatch it.uv add/uv removeupdate the lock automatically;uv syncinstalls / 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];devis 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-versionpins 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
venvandpipcommands. Same ideas and flags as pip, prefixed withuv.Use it for existing projects based on
requirements.txtthat 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.txtand uv projects.uv add -rimports a list;uv exportwrites 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.
uvxruns a tool in a temporary cached env;uv tool installkeeps 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 --scriptwrites an inline metadata block;uv runcreates a temporary env for it.Use it for small utility scripts you share or run occasionally, with no project folder.
# /// 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
.venvin the editor and notebooks. uv makes a normal.venvfolder, 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.
Exercise 2: Upgrade one package¶
Upgrade only pandas in the lock file and environment.
Exercise 3: Tool without installing¶
Lint the project with Ruff without adding it to the project, then export a requirements.txt.
Previous: 11 - Python Virtual Environment | Index: All guides | Next: 13 - Pydantic