This guide covers the essentials of using uv for modern Python development. The workflow is organized from simple scripts to full project management.
uv installs as a standalone binary.
# MacOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"One of uv's best features is running single Python files that declare their own dependencies. You don't need a virtual environment or a project folder.
The Method: Add PEP 723 metadata at the top of your file.
Create a file named scraper.py:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://httpbin.org/json")
pprint(resp.json())How to run it:
uv run scraper.pyWhat happens: uv creates a temporary, cached environment, installs requests and rich, downloads Python 3.12 if you don't have it, and runs the script immediately.
For actual applications, uv uses the standard pyproject.toml.
uv init my-project
cd my-projectThis creates a pyproject.toml, a .python-version file, and a src directory.
Forget manually editing files. Use the CLI to manage pyproject.toml and uv.lock.
# Add a package
uv add pandas
# Add a specific version constraint
uv add "numpy<2.0"
# Add a development dependency (e.g., testing tools)
uv add --dev pytest
# Remove a package
uv remove pandasuv manages the virtual environment for you automatically.
# Run a specific file in the project context
uv run src/main.py
# Or, if you configured a [project.scripts] entry point
uv run my-app-nameuv manages Python installations itself. You generally don't need pyenv or system Python anymore.
The .python-version file in your project root dictates which version is used.
# Pin the project to Python 3.11
uv python pin 3.11# List available versions
uv python list
# Explicitly install a version
uv python install 3.13uvx is the tool runner (equivalent to npx in Node.js or pipx). Use this for global command-line tools you don't want to install in your project.
# Run ruff (linter) without installing it globally
uvx ruff check .
# Run a fun CLI tool (installs temporarily)
uvx cowsay "Hello uv"
# Run a tool with specific Python version
uvx --python 3.10 some-legacy-toolWhile uv uses uv.lock and pyproject.toml by default, you often need to interact with legacy systems.
If you have a requirements.txt and want to migrate to pyproject.toml:
uv add -r requirements.txtIf your deployment pipeline doesn't support uv yet and needs a requirements.txt:
uv export --format requirements-txt > requirements.txt| Goal | Command |
|---|---|
| Start new project | uv init <name> |
| Add library | uv add <package> |
| Run script | uv run <script.py> |
| Run CLI tool | uvx <tool> |
| Lock dependencies | uv sync |
| Update all deps | uv lock --upgrade |
| Change Python ver | uv python pin 3.12 |