If you develop with Python professionally, you've probably at least heard of uv, the "extremely fast Python package and project manager, written in Rust."
uv claims to be 10-100x faster than pip depending on the platform. Installation (uv sync
) and resolution (uv lock
) benchmarks against pip-compile and other dependency management packages are pretty convincing.
While it would be accurate to describe uv as a "faster pip," uv has a much broader scope. It goes a long way towards removing some of the most onerous parts of Python package management.
Because of uv's features and its faster speed, we're switching to uv from pip to manage dependencies for our projects.
1. uv provides a universal lockfile.
No longer will your lockfile change if you install dependencies on a different platform than the one on which the lockfile was created.
2. uv allows managing all dependencies in pyproject.toml.
I've worked on projects that used pip-sync with requirements files for multiple platforms and additional files for dev dependencies. This led to 8 different requirements.txt files.
With uv, you can use environment markers for platform-specific dependencies (e.g. uv add "jax; sys_platform == 'linux'"
). Additionally, uv supports dependency groups, including the default dev group (e.g. uv add --dev pytest
).
3. uv can install Python versions.
While other tools can do this as well, it's incredibly handy to have built-in.
4. uv can run scripts, including scripts with dependencies, with no virtual environment setup required.
uv uses the PEP 723 format for declaring dependencies as comments at the top of a script (example here)
This means you can hand someone a Python file, tell them to run it with uv run script.py
, and it will automatically run in an isolated environment with appropriate dependencies. 🤯
5. uv can manage and run standalone tools.
You can install a CLI tool like ruff with uv tool install ruff
or run it as a one-off with uvx ruff
(equivalent to uvx tool run ruff
).
Recently, I switched from zsh shell to fish shell and migrated my command history to fish using a single command: uvx zsh-history-to-fish
.
Python itself is productive, and uv’s speed and features make development even more efficient. A universal lockfile, centralized dependency management, and the ability to run scripts without having to set up a virtualenv make uv a useful addition to your toolkit.