If you use python and aren't using uv yet, you should absolutely go try it! It's an all-in-one environment manager for Python that handles getting the correct interpreter and the correct packages, and it's distributed as a static binary with no dependency on Python. It makes Python an incredibly enjoyable ecosystem to work with because you can get your environment bootstrapped without worrying about having the right version of Python (or the right version of pip) to get your venv set up correctly.

uv also supports PEP 723 – Inline script metadata. That means you can write comments like this:

# /// script
# requires-python = "==3.13.*"
# dependencies = [
#   "termcolor"
# ]
# ///

from termcolor import cprint

cprint("Green text!", "green")

Then you can run your script with uv run:

You can also add the -q or --quiet flag to suppress the info about it reading the inline metadata and installing the dependencies for you.

You can take this one step further. You can set a shebang to automatically invoke your script with uv, making it a self-contained single-file Python program that automatically has its dependencies set up for it! The GNU coreutils env command allows you to specify the -S flag to split the argument and pass the flags to the command being invoked.

So we can write our shebang line like this:

#!/usr/bin/env -S uv run --script --quiet

When we execute our script, it does everything automatically:

There is one caveat to this approach: BusyBox. On most Linux systems you have GNU coreutils, and on macOS you have some other flavor of coreutils that supports the env -S flag, but the flag is not universal.

There's a simple enough workaround for this problem: install the GNU coreutils.

If you would like to avoid the GPL, you can use the MIT-licensed uutils-coreutils instead. It's a Rust reimplementation of GNU coreutils. It's a few megabytes larger, but is permissively licensed and written in a memory-safe language.