Getting Started With uv, the Python Package & Project Manager
Table of Contents
📝 From my notes: living personal cheatsheets.
uv is an extremely fast Python package and project manager, written in Rust. A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
Docs • GitHub • Skip to practical tips
Installation
See the docs for more options (cargo, WinGet, Docker…).
GNU+Linux & macOS
|
# for macOS with brew
Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Drop-in compatible API
uv provides a drop-in replacement for pip
:
pip command | uv command |
---|---|
pip install | uv pip install |
pip-compile | uv pip compile |
pip-sync | uv pip sync |
python -m venv .venv | uv venv |
pip-compile requirements.in -o requirements.txt | uv pip compile requirements.in -o requirements.txt |
These commands work directly with the virtual environment, in contrast to uv’s primary interfaces where the virtual environment is managed automatically.
uv
doesn’t rely on or invoke pip
. The pip interface is named as such to highlight its dedicated purpose of providing low-level commands that match pip’s interface and to separate it from the rest of uv’s commands which operate at a higher level of abstraction.
Create a virtual environment
To create a virtual environment (venv) in the current directory:
The venv will be in the .venv/
directory. You can choose a different path with uv venv /path/to/venv
.
To activate the venv (often unnecessary, read below): source .venv/bin/activate
.
uv
doesn’t store venvs in a centralised location; there’s no . See issue 1495.uv venv list
Working with projects
uv
helps manage Python projects with dependencies defined in pyproject.toml
.
Creating a project
# Or initialise in current directory.
This creates a basic project structure:
.
├── .git/ # Initialised git repository.
├── .gitignore # Python-specific gitignore.
├── .python-version # Project's Python version.
├── README.md # Empty readme file.
├── pyproject.toml # Dependencies and metadata.
├── hello.py # Sample Python script.
When you run project commands (like uv run
), uv
will create:
.venv/
: Project’s virtual environmentuv.lock
: Exact dependency versions
Managing dependencies
# Add a dependency.
# Remove it.
# Update specific package.
Dependencies are declared in pyproject.toml
and locked in uv.lock
. Commit both files to version control for reproducible builds.
Want to migrate from poetry/pip-tools to uv? Try mkniewallner/migrate-to-uv.
Project environments
uv
automagically creates and manages a project-specific virtual environment in .venv
. When using uv run
, it ensures your code executes in this environment with the correct dependencies:
# Run with project dependencies.
# Add temporary dependencies for specific runs.
# Use a specific Python version.
Installing requirements
To install requirements from a requirements.txt
file:
Syncing the environment
To synchronise the environment with the project’s dependencies, use uv sync
.
uv sync
will remove any packages from your virtual environment that are not explicitly listed as dependencies in your requirements.txt
, pyproject.toml
, or lockfile.
This ensures that all dependencies specified in your pyproject.toml
or requirements.txt
are installed, and any extraneous packages are removed.
Running Python scripts and commands
uv run
ensures commands run in a Python environment. It’s useful for:
- Running Python scripts:
uv run script.py
- Running Python modules:
uv run -m pytest
- Running commands in project environments:
uv run python
When used in a project, if a virtual environment can be found in the current directory or a parent directory, the command will be run in that environment.
Outside a project, the command will be run in the environment of the discovered interpreter.
Common use cases:
# Run a script with dependencies from requirements.txt
# Run pytest with extra dev dependencies.
# Run a command in an isolated environment.
# Run from a remote repository.
# Run a remote script (be careful!)
Tools
Many Python packages provide applications that can be used as tools. uv has specialized support for easily invoking and installing tools.
If you want a globally available tool for your user (e.g. git-sumi), run:
Now you can use git-sumi
from anywhere on your system, as it’s installed in a bin directory in your PATH
.
Running tools without installing them
uvx
runs a tool without installing it:
uvx
is an alias for uv tool run
.
If you want to quickly format a file with ruff
without installing it:
Clearing the cache
uv uses aggressive caching to avoid re-downloading (and re-building) dependencies that have already been accessed in prior runs.
# Remove all cached packages.
# Clean cache for specific package.
# Remove only unused cache entries.
Practical tips
Run any Python version with any number of dependencies
All without manually creating venvs or installing anything globally:
For quick prototyping, you can run Jupyter notebooks with dependencies:
Or start an interactive Python shell with a specific Python version and dependencies:
Reproducible Jupyter notebooks with juv
juv is a uv-powered toolkit for creating reproducible Jupyter notebooks.
# Install globally.
# Or run without installing.
Here’s what you can do with it:
# Create a new notebook.
# Add dependencies to a notebook.
# Launch notebook with dependencies.
# Add temporary dependencies.
# Convert Python scripts to notebooks on the fly.
# Lock dependencies.
# Export dependencies in pip-compatible format.
Dependencies are stored in the notebook’s metadata, so you can share notebooks with others and ensure they have the correct environment.
Use uv as your shebang line
From Rob Allen’s blog (via HN):
Use uv
in your script’s shebang line to automatically handle dependencies:
#!/usr/bin/env -S uv run --script
This allows you to create executable Python scripts that manage their own dependencies. You can declare dependencies inline (PEP-723):
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.13"
# dependencies = ["cowsay"]
# ///
Make the script executable (chmod +x script.py
), and you’re good to go!