Skip to content

Managing Python dependencies with uv

Christophe TREMBLAY-GUILLOUX
Christophe TREMBLAY-GUILLOUXLinux systems engineer

uv manages the dependencies and the virtual environment of a Python project. Everything rests on three files, always in the same order:

pyproject.toml ──uv lock──▶ uv.lock ──uv sync──▶ .venv/
what you want exact versions what is installed
(ranges >=, <)
FileRoleIn git
pyproject.tomlWanted dependencies, with version rangesYes
uv.lockExact resolved versions, for every platformYes
.venv/Environment installed on the machineNo
StepCommand
Add a dependencyuv add httpx
Add a dev dependencyuv add --dev pytest
Remove a dependencyuv remove httpx
After a git pulluv sync
pyproject.toml edited by handuv lock, then uv sync
Upgrade one packageuv lock --upgrade-package httpx
Upgrade everythinguv lock --upgrade
Run a commanduv run pytest
Before committinguv lock --check

uv add and uv remove update all three layers at once. uv run syncs the .venv before running the command.

If the project declares its dev tools as optional dependencies ([project.optional-dependencies]) rather than as a dev group, use uv add --optional dev pytest and uv sync --extra dev.

bash
uv sync --locked
uv run pytest
bash
uv cache prune --ci
uv sync --locked --no-dev

uv cache prune --ci empties the cache of downloaded packages. Without it, the cache keeps every installed version and ends up filling the disk.

  • --locked installs into the .venv the packages at the exact versions listed in uv.lock, and fails if it no longer matches pyproject.toml. Use it in CI and in production: a pyproject.toml committed without its lock is caught.
  • --frozen also installs the versions from uv.lock, but without checking that it still matches pyproject.toml. Avoid it, except in special cases.