I was trying to share a quick Python script with a colleague. The usual dance: “first pip install these three packages, make sure you’re using Python 3.11+, oh and activate a venv first…” It’s tedious. Then I discovered uv run can handle all of this in one command.
Inline dependencies (the killer feature) Link to heading
PEP 723 introduced a standard way to declare dependencies directly in a Python script using a special comment block:
# /// script
# requires-python = ">=3.12"
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
response = requests.get("https://api.github.com")
print(response.json())
When you run this with uv run script.py, uv reads the metadata, creates an isolated environment with those exact dependencies, and runs the script. No requirements.txt, no pyproject.toml, no venv activation. Just run it.
You can add dependencies to a script automatically:
uv add --script example.py 'requests<3' 'rich'
This inserts the # /// script block for you.
Important: When a script has inline metadata, project dependencies are completely ignored. The script is self-contained.
Standalone executable scripts Link to heading
Add a shebang and you can run scripts directly without typing uv run:
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["httpx"]
# ///
import httpx
print(httpx.get("https://example.com").text[:100])
Make it executable with chmod +x script.py, then just ./script.py. The -S flag to /usr/bin/env passes the rest of the line as arguments, which is what makes this work.
I’d recommend this for utility scripts you use often. Share them on GitHub and anyone with uv installed can run them directly.
Ad-hoc dependencies Link to heading
Don’t want to modify the script? Use --with:
uv run --with pandas script.py
uv run --with 'numpy>=2.0' --with matplotlib script.py
This is handy for quick experiments or when testing a script with a newer version of a dependency.
Running from URLs Link to heading
You can fetch and run scripts directly from the internet:
uv run https://raw.githubusercontent.com/user/repo/main/script.py
If the remote script has PEP 723 metadata, uv handles the dependencies automatically. I’ve used this to share utility scripts with teammates - just send them a GitHub raw URL.
Obviously, don’t run random scripts from the internet. Review the code first.
Python version selection Link to heading
Need a specific Python version?
uv run --python 3.12 script.py
If Python 3.12 isn’t installed, uv downloads it for you. Combined with inline metadata’s requires-python, this makes scripts genuinely portable.
uv run vs pipx Link to heading
Both can run Python tools without polluting your global environment, but they serve different purposes:
- pipx is for installing CLI tools you use regularly (
pipx install black) - uv run is for ad-hoc scripts and one-off execution
I’d recommend uv tool install for tools you use daily (ruff, black, pre-commit) and uv run for everything else.
Is uv ready to replace pip/poetry? Link to heading
For me, yes. I’ve migrated all my projects. The benefits:
- Speed - Installs are 10-100x faster than pip
- Lockfiles - Reproducible installs by default
- All-in-one - Replaces pip, pip-tools, virtualenv, pyenv
- Just works - Fewer edge cases than poetry
The only rough edge: some older packages with complex build requirements occasionally fail. But that’s rare.
Further reading Link to heading
- uv scripts guide - official documentation
- PEP 723 - the inline script metadata spec
- Inline script metadata - PyPA canonical spec
- Publishing Python packages to Artifact Registry with uv - using uv for package publishing
- Dependabot with uv - keeping uv dependencies updated