Save that as script.py and you can use "uv run script.py" to run it with the specified dependencies, magically installed into a temporary virtual environment without you having to think about them at all.
Claude 4 actually knows about this trick, which means you can ask it to write you a Python script "with inline script dependencies" and it will do the right thing, e.g. https://claude.ai/share/1217b467-d273-40d0-9699-f6a38113f045 - the prompt there was:
Write a Python script with inline script
dependencies that uses httpx and click to
download a large file and show a progress bar
One gotcha I caught myself in with this technique is using it in a script that would remediate a situation where my home has lost internet and needed the router to be power cycled. When the internet is out, `uv` cannot download the dependencies specified in the script, and the script would fail. Thankfully I noticed this problem after writing it but before needing it to actually work, and refactored my setup to pre-install the needed dependencies. But don't make the same mistake I almost made! Don't use this for code that may need to run airgapped! Even with uv caching you may still get a cache miss.
This is my absolute favourite uv features and the reason I switched to uv.
I have a bunch of scripts in my git-hooks which have dependencies which I don't want in my main venv.
#!/usr/bin/env -S uv run --script --python 3.13
This single feature meant that I could use the dependencies without making its own venv, but just include "brew install uv" as instructions to the devs.
Note that this only works for single-file scripts.
If you have a project with modules, and you'd like a module to declare its dependencies, this won't work. uv will only get those dependencies declared in the invoked file.
I love this feature of uv but getting linters/language servers to pick up the venv when editing the files is a bit of a pain. I currently have a script 'uv-edit' which I am using to run Neovim with the correct environment:
I wish there was a straightforward way to let VS Code pick up the venv that uv transparently creates.
Out of the box, the Python extension redlines all the third-party imports.
As a workaround, I have to plunge into the guts of uv's Cache directory to tell VS Code the cached venv path manually, and cross fingers that it won't recreate that venv too often.
Love this feature of UV. Here's a one-liner to launch jupyter notebook without even "installing" it:
uv run --with jupyter jupyter notebook
Everything is put into a temporary virtual environment that's cleaned up afterwards. Best thing is that if you run it from a project it will pick up those dependencies as well.
in scripts for including per-script dependencies. This is language agnostic as long as the interpreter and its dependencies are available as guix packages. I think there may be a similiar approach for utilizing nix shells that way as well.
Oh nice, I was already a happy user of the uv-specific shebang with in-script dependencies, but the `uv lock --script example.py` command to create a lock file that is specific to one script takes it to another level! Amazing how this feels so natural and yet only appeared after 20+ years of Python packaging.
I recently found a small issue with `uv run`. If you run a script from outside the project folder, it looks for the pyproject.toml on the folder from which you are calling `uv run`, not on the folder where the python script is located (or its parents)! Because of that scripts that store their dependencies in a pyproject.toml cannot be run successfully using a “bare” `uv run path/to/my/script.py` from outside the project folder.
You can work around this surprising behavior by always using inline dependencies, or by using the `--project` argument but this requires that you type the script path twice which is pretty inconvenient.
Other than that uv is awesome, but this small quirk is quite annoying.
It’s a pretty minimal wrapper around “uv” and “iPython” to provide the functionality from the article, but for Jupyter notebooks. It’s similar to other projects, but I think my implementation is the least intrusive and a good “citizen” of the Jupyter ecosystem.
Which provides a companion Jupyter plugin to manage the embedded script dependencies of noteboooks with a UI. Warning — this one is partially vibe-coded and very early days.
This is pretty great. Passing python code out to my students is usually also confronted with the question of "How do I run it?", which is usually terrible to answer. Now, I can just tell them to get uv (single command) and run it.
There are a lot of bits and pieces that are clicking into place lately in the Python ecosystem. Recently I've been using the combination of Marimo and these uv script dependencies for building reproducible rwporting and diagnostic tooling for other teams.
How many package managers can one language have? Its a simple language but setting it up is just incredibly bad. Maybe this is the one or should I wait for the next?
Why doesn't pip support PEP 723? I'm all for spreading the love of our lord and savior uv, but it should be necessary to have an official implementation.
As a tangent, one issue I face is how to force cursor to use uv over pip. I have placed it in rules and also explicitly add a rules.yml file in every agent conversation. It still tries to push through pip 4 out of 10 times. Any recommendations on best practice to force cursor to use uv will make a significant dent in productivity
Oh this looks amazing! I had pretty much stopped using Python for my one-off scripts because of the hassle of dependencies. I can't wait to try this out.
> Python doesn't require a requirements.txt file, but if you don't maintain this file, or neglect to provide one, it could result in broken functionalities - an unfortunate circumstance for a scripting language.
I kinda always struggled to grok python's package management and module system.
UV is finally making things more understandable and just as good as the nodejs packaging and module system that I'm more comfortable with. This new feature is kinda awesome. Even surpassing the DX of the node ecosystem.
One case this may not work well is when one of the dependencies is Pytorch. Uv has explicit support for Pytorch ( https://docs.astral.sh/uv/guides/integration/pytorch/ ) but with the script headers I don't see a way to pick the most appropriate wheel index (cpu vs cuda vs rocm)
This is a pretty nice feature which I use quite often. There are still some edge cases where it cannot be used to the fullest extent though. https://github.com/astral-sh/uv/issues/14472 for example.
I hate such poor docs that don't explain how things work, and instead prefer hiding behind some "magic".
> Constraints can be added to the requested dependency if specific versions are needed:
> uv run --with 'rich>12,<13' example.py
Why not mention that this will make uv download specified versions of specified packages somewhere on the disk. Where? Are those packages going to get cached somewhere? Or will it re-download those same packages again and again every time you run this command?
As a non-Python person, I find “uv” to be a confusing name.
For a long time I assumed it’s a Python wrapper for libuv which is a much older and well-known project. But apparently it’s Python package manager #137 “this one finally works, really, believe me”
Uv: Running a script with dependencies
(docs.astral.sh)507 points by Bluestein 21 July 2025 | 171 comments
Comments
It's an implementation of Python PEP 723: https://peps.python.org/pep-0723/
Claude 4 actually knows about this trick, which means you can ask it to write you a Python script "with inline script dependencies" and it will do the right thing, e.g. https://claude.ai/share/1217b467-d273-40d0-9699-f6a38113f045 - the prompt there was:
Prior to Claude 4 I had a custom Claude project that included special instructions on how to do this, but that's not necessary any more: https://simonwillison.net/2024/Dec/19/one-shot-python-tools/I have a bunch of scripts in my git-hooks which have dependencies which I don't want in my main venv.
#!/usr/bin/env -S uv run --script --python 3.13
This single feature meant that I could use the dependencies without making its own venv, but just include "brew install uv" as instructions to the devs.
If you have a project with modules, and you'd like a module to declare its dependencies, this won't work. uv will only get those dependencies declared in the invoked file.
For a multi-file project, you must have a `pyproject.toml`, see https://docs.astral.sh/uv/guides/projects/#managing-dependen...
In both cases, the script/project writer can use `uv add <dependency>`, just in the single-file case they must add `--script`.
Out of the box, the Python extension redlines all the third-party imports.
As a workaround, I have to plunge into the guts of uv's Cache directory to tell VS Code the cached venv path manually, and cross fingers that it won't recreate that venv too often.
#!/usr/bin/env -S guix shell python python-requests python-pandas -- python3
in scripts for including per-script dependencies. This is language agnostic as long as the interpreter and its dependencies are available as guix packages. I think there may be a similiar approach for utilizing nix shells that way as well.
[0]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-shell...
You can work around this surprising behavior by always using inline dependencies, or by using the `--project` argument but this requires that you type the script path twice which is pretty inconvenient.
Other than that uv is awesome, but this small quirk is quite annoying.
https://github.com/tobinjones/uvkernel
It’s a pretty minimal wrapper around “uv” and “iPython” to provide the functionality from the article, but for Jupyter notebooks. It’s similar to other projects, but I think my implementation is the least intrusive and a good “citizen” of the Jupyter ecosystem.
There’s also this work-in-progress:
https://github.com/tobinjones/pep723widget
Which provides a companion Jupyter plugin to manage the embedded script dependencies of noteboooks with a UI. Warning — this one is partially vibe-coded and very early days.
> Python doesn't require a requirements.txt file, but if you don't maintain this file, or neglect to provide one, it could result in broken functionalities - an unfortunate circumstance for a scripting language.
https://twitter.com/_damnever/status/1697247813854503250
Fun with uv and PEP 723
640 points | 227 comments
He does all the legwork and boils it down into an easily-understandable manner.
He’s also a user her in this thread at simonw. Just an immensely useful guy.
Works well, but the compilation of the dependencies (first run of the script) can be a bit long. A problem which uv (Python) probably won’t have…
[1] https://github.com/xcode-actions/swift-sh
this is neat af. my throw-away scripts folder will be cleaner now.
https://gist.github.com/pythoninthegrass/e5b0e23041fe3352666...
tl;dr
Installs 3 deps into the uv cache, then does the following:
1. httpx to call get request from github api
2. sh (library) to run ls command for current directory
3. python-decouple to read an .env file or env var
> Constraints can be added to the requested dependency if specific versions are needed:
> uv run --with 'rich>12,<13' example.py
Why not mention that this will make uv download specified versions of specified packages somewhere on the disk. Where? Are those packages going to get cached somewhere? Or will it re-download those same packages again and again every time you run this command?
For a long time I assumed it’s a Python wrapper for libuv which is a much older and well-known project. But apparently it’s Python package manager #137 “this one finally works, really, believe me”
https://github.com/pmarreck/yt-transcriber
A commandline youtube transcription tool I built that runs on Mac (nix-darwin) which automatically pulls in all the dependencies it needs