uv is “an extremely fast Python package installer and resolver, written in Rust” from https://astral.sh. Recently, I have started using uv in my day-to-day Python workflows. After a few weeks of usage I am sold! uv will be my go-to package manager for Python projects moving forward. It is MUCH faster than pip and I really like the new workflow it provides me with uv pip compile
and uv pip sync
.
TL/DR
I am now using uv
instead of pip
for most of my projects. My workflow looks like this:
Why uv?
For all of my future projects I plan to use uv because:
- uv is much faster than pip.
- uv pip compile and uv pip sync are a better workflow for managing dependencies.
- uv enforces best practices by forcing you to use virtual environments.
There is one exception. For package development, I plan to still use poetry (https://python-poetry.org) because it some features that are specific to package development that uv does not have (e.g. like poetry publish
).
Install uv
See https://github.com/astral-sh/uv for more details.
Workflow comparison
Creating a virtual environment
Installing first package
Define your initial requirements.
Then install the requirements and the transitive dependencies.
Adding new packages
Update requirements.in to include the additional packages you want to install.
Then install the new packages and the transitive dependencies.
Removing packages
Up until now, other than the speed improvements it may not be obvious why uv is better than pip. Lets say we want to remove the pandas package from our project. This is an area where uv really shines. With uv, we can remove the package from requirements.in and run uv pip compile
and uv pip sync
to update our environment.
With pip, we need to remove the package from requirements.txt and delete the current virtual environment,and then re-create it. If you were to use pip uninstall pandas
, it would remove pandas from our environment, but not all of the transitive dependencies that pandas brought in that we no longer require.
Using aliases
It is true that for parts of the workflow using uv requires more typing. I have found these two aliases to be very helpful in my workflow.
You can add these to your .bashrc
or .zshrc
file to make them available in all of your projects.
Now when I start a new project I run:
Whenever I make a change to requirements.in I run: