I started using uv
as my default package manager. I’ve only ever used pip
, but some echoes of uv
had been reverberating in my head, so I gave it a try. And, after a couple months, I’m still using it. I’ve enjoyed the speed of installation and general dependency management, though have endured a few frustrating loops. For experienced uv
practitioners, additional advice or recommendations would be appreciated.
Installation and Setup
For reference, I do almost all of my work within PyCharm
on Windows machines, having PyCharm create a virtual environment for me when creating a new project through its GUI. For most package installation, however, I resort to the command line: Alt + F12
, then pip install package
.
While I originally started by following this same setup and beginning with pip install uv
and then uv add package
, the uv
docs seem to recommend a standalone installation outside of an individual environment. I suspect the rational is that this is a tool and shouldn’t be tied to the dependencies of a particular project. uv
and other such tools should be treated separately. (Similar to, e.g., an Excel workbook: you don’t want each workbook to have its own Excel instance, but a single Excel instance that can operate with any particular workbook.)
Since I work with a lot of VMs and would prefer not to have to keep updating a plethora of tool sets, I installed (well, downloaded) uv.exe
to a shared directory which all of my Windows VMs can access. Then, I’ve added the containing directory to the $PATH of each VM so that I can just run uv
everywhere. No issues with this approach so far.
Project Setup
The easiest way to get started is to then run uv init --bare
in the directory which will create just a pyproject.toml
. uv
will create different folder structures, and it might be worth exploring if you have a preference:
uv init --package
- for creating a package that is meant to be
pip
installed
- for creating a package that is meant to be
uv init --lib
- for creating a library
uv init
- this creates a sample
main.py
file which seems a bit silly
- this creates a sample
PyCharm will also offer to initialise your project using uv
(just pass in the path to the downloaded executable).
Package Management
At its simplest, instead of using pip install package
, you use uv add package
. This covers the majority of my uses, and uv
seems (i.e., not actually tested) a bit faster than pip
.
To remove a package, run uv remove package
.
The other commands are a bit harder to recall sometimes, though typically if you’re not sure what they are and don’t want to look them up, just run uv pip <command>
(e.g., uv pip install package
)
Here are some other useful commands:
uv sync
- Installs the packages from the library.
- E.g., after running
git clone
uv sync --upgrade-packag
epackage
- Upgrade the specified package
uv lock --upgrade
and thenuv sync
- Finding latest version of all dependencies (within constraints) and then use
uv sync
to upgrade to the new versions
- Finding latest version of all dependencies (within constraints) and then use
uv add --dev pytest
- Add dependencies to
dev
rather than required withinpyproject.toml
- This command is syntactic sugar for the more generic:
uv add --group test pytest
- Using
uv add --group NAME PACKAGE
, you can create arbitrary dependency groups. - You can change what default groups should be available by using:
- Add dependencies to
# inside pyproject.toml
[tool.uv]
default-groups = ['dev']
uv sync --no-group dev
- By default, I think dev all groups are installed, so use this command to install dependencies, but not the
dev
group. - With some sugar (just for
dev
), try:uv sync --no-de
v
- By default, I think dev all groups are installed, so use this command to install dependencies, but not the
Some other commands which I haven’t used, but might be valuable depending on your workflow.
uv tool install toolname
anduv tool run toolname
- If you use linters, etc. from the command line. All of my tools are just part of PyCharm.
uv build
- Prepares the code for distribution. By default, it will create both a wheel (
*.whl
) and a zipped archive (*.tar.gz
or*.zip
) containing your code.
- Prepares the code for distribution. By default, it will create both a wheel (
uv publish
- Publish your package to
pypi
(by default; or some other package index). - To do this:
export UV_PUBLISH_TOKEN=<PYPI_TOKEN>
uv publish
- For a separate repository, you can use the
--publish-url
flag.
- Publish your package to
Summary
Compared with my brief attempt to wrestle poetry
(I eventually proved successful), I’ve been particularly pleased that uv
has always ‘just worked’. Download (or pip install
) the executable, and then call it.