uv is an extremely fast package and project manager for Python, written in Rust. I hear you mumbling, another package manager for Python? Bro, this time is different, hear me out, uv really is the future. In this post we’ll spend some minutes learning how to use it.
What can I do with it?
Lots of things, but from the top of my head:
- Install packages, duh, but 10-100x faster than pip, the official package manager for Python.
- Install and manage Python versions; goodbye pyenv.
- It’s also a project manager; sayonara Poetry.
- Run and install command-line tools, alla npx.
- Workspaces, what?!
Installation
There are plenty of ways to get this puppy up and running in our machine. The first one, if you’re lucky enough to be on Linux or macOS:
$ curl -LsSf https://astral.sh/uv/install.sh | sh
After the installation, we have to restart our shell (just type exit
in your terminal). That’s because the installer added uv
to our PATH
.
NOTE
If you’re in Windows 🤢:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
For Christ’s sake, you can even install it with pip
!
pip install uv
Anyways, once you’ve installed it, and as a sanity test, run:
$ uvAn extremely fast Python package manager.
Usage: uv [OPTIONS] <COMMAND>
TIP
Check the docs for uninstallation if you need to.
Installing Python Versions
uv
can also install and manage Python versions:
$ uv python install
That would get us the latest version, but if you want to install a specific one, just say it:
$ uv python install 3.12
NOTE
If you run the command above (regardless if you’re in a project folder), it will install Python in ~/.local/share/uv/python/cpython-3.13.3-macos-aar
, and create a symlink to it in ~/.local/bin/python3.13
.
To see a list of the available and installed Python versions:
$ uv python list
IMPORTANT
We don’t need to install Python to get started; If Python is already installed on your system, uv
will detect and use it.
Projects
uv
supports managing Python projects, which define their dependencies in a pyproject.toml
file. Like in other languages, we can create a new Python project using the uv init
command:
uv init my-proj
That will create the following project structure within the my-proj
folder:
.├── .python-version├── README.md├── main.py└── pyproject.toml
TIP
If you already have a project folder, let’s say you already have the my-proj
folder, you can run just uv init
within the folder.
The main.py
file contains a simple “Hello world” program. Try it out with uv run
:
$ cd my-proj$ uv run main.pyUsing CPython 3.13.2 interpreter at: /usr/bin/python3.13Creating virtual environment at: .venvHello from my-proj!
Now, if we list the content of our project:
$ ls -a.├── .git├── .gitignore├── .venv│ ├── bin│ ├── lib│ └── pyvenv.cfg├── .python-version├── README.md├── main.py├── pyproject.toml└── uv.lock
That’s right, uv
has created a virtual environment (in .venv
folder), and initialized a git
repo for us. From a project point of view, the pyproject.toml
contains our project’s metadata (sort of the package.json
in Node.js):
[project]name = "hello-world"version = "0.1.0"description = "Add your description here"readme = "README.md"dependencies = []
Managing Dependencies
Managing dependencies is easy. Let’s say we want to install marimo:
uv add marimo
Marimo includes a tutorial, so let’s run it, to verify it’s installed:
uv run marimo tutorial intro
WARNING
If you try to run:
marimo tutorialzsh: command not found: marimo
Your shell will complain! That’s because when we run uv add marimo
, uv installs marimo into a virtual environment (under the .venv
folder). This environment is isolated, meaning the marimo executable is only available when the virtual environment is activated or when you explicitly use uv run
to access it.
I hope that was enough to get you started; feel free to check the official docs, they’re awesome.