uv generalities
Repository :
https://pypi.org/
Architecture & Nature :
uv is an extremely fast, standalone Python package and project manager written in Rust.
It replaces pip, pip-tools, pipx, poetry, pyenv, virtualenv, build and twine in a single unified binary.
It must be installed globally at the system level (not inside a virtual environment).
Execution model : uv run VS manual venv activation :
– With active venv : Once source .venv/bin/activate is run, standard direct commands (python script.py, pytest, ruff) run inside the venv as usual.
– Without active venv (recommended) : uv run <command> automatically discovers the project .venv (or creates/syncs it if missing) and runs the command in isolation without altering the host shell environment.
uv-pip incompatibility issues
Pip allows us to name our virtual environment directory as we want : venv, .venv, anything…
But uv waits for .venv and not other thing.
By default, you will get that kind of error during some uv commands such as :
warning: `VIRTUAL_ENV=venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead.
To overcome that issue while still using another directory name, we have 2 options:
– Set a env var with the wished name such as :
UV_PROJECT_ENVIRONMENT=venv
– add the --active flags in uv commands.
Python version management
List available and installed Python versions :
uv python list
Scans the system to detect both uv-managed builds, externally installed versions (OS package managers, Homebrew, pyenv, etc.), and downloadable versions from the registry.
To filter and show only installed versions on the machine :
uv python list --only-installed
To find the exact binary location of a version :
uv python find 3.12
Install a specific Python version (downloads standalone builds) :
uv python install 3.12
uv python install 3.10 3.11 3.12
Pin Python version for the current project (.python-version file) :
uv python pin 3.12
Creates a standard .python-version file at the project root.
Enforces this exact Python version for all local uv commands (and automatically downloads it on the fly if missing).
List / inspect commands
Show visual dependency tree (project workspace) :
uv tree
or for flat environment / pip mode :
uv pip tree
List installed packages :
uv pip list
Check installed packages compatibility and integrity :
uv pip check
Detects broken requirements and version conflicts among installed packages without modifying them.
Show installed package metadata and files location :
uv pip show --files foo-package
Project dependency management
Add dependencies to pyproject.toml and update lockfile :
uv add requests
uv add 'requests>=2.31.0,<3.0'
Add development / test dependencies :
uv add --dev pytest
Remove a dependency :
uv remove requests
Generate / Update lockfile without modifying environment :
uv lock
or upgrade all locked versions :
uv lock --upgrade
Sync virtual environment with lockfile (installs/removes packages to match exactly) :
uv sync
or sync all workspace packages and extras :
uv sync --all-packages
Pip drop-in replacement mode (uv pip)
Create a virtual environment :
uv venv
with specific Python version :
uv venv --python 3.10
Install packages into venv (auto-detects local .venv without manual activation) :
uv pip install requests python-dateutil
uv pip install 'pycryptodome==3.20.0'
uv pip install -r requirements.txt
Install packages into a specific venv :
uv pip install --python .venv_ide requests python-dateutil
uv pip install --python .venv_ide 'pycryptodome==3.20.0'
uv pip install --python .venv_ide -r requirements.txt
Compile dependencies to requirements.txt (replaces pip-compile) :
uv pip compile pyproject.toml -o requirements.txt
or from requirements.in :
uv pip compile requirements.in -o requirements.txt
Upgrade a package :
uv pip install --upgrade foo-package
Force reinstall :
uv pip install foo-package --force-reinstall
Install in system environment (Docker only / equivalent to –break-system-packages) :
uv pip install --system requests
Application and dependencies : development and build
Build, package and publish a library with uv
Standard pyproject.toml (PEP 621) :
[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "service-lib" version = "0.1.0" description = "My package description" authors = [ {name = "David"}, ] requires-python = ">=3.10" classifiers = [ "Framework :: Flask", "Programming Language :: Python :: 3.10", ] dependencies = [ "flask==2.3.1", "flask-cors==4.0.0", "requests==2.31.0", "gunicorn==21.2.0", "models-lib", ] |
1. Create the virtual environment :
uv venv --python 3.10
2. Generate the deterministic lockfile (uv.lock) :
uv lock
3. Synchronize environment and install package in editable mode :
uv sync
4. Build distribution archives (sdist and wheel into dist/) :
uv build
5. Publish package to repository (replaces twine) :
uv publish --publish-url https://your-repo/legacy/ dist/*
Multiple packages development : uv Workspaces
Workspaces natively replace manual .pth files and pip install -e links.
They maintain a single root .venv and a single unified uv.lock for all sub-packages in the monorepo.
Root pyproject.toml :
[project] name = "monorepo-root" version = "0.1.0" requires-python = ">=3.10" [tool.uv.workspace] members = ["libs/*", "services/*"] |
Sub-package services/service-lib/pyproject.toml consuming local models-lib :
[project] name = "service-lib" version = "0.1.0" dependencies = [ "models-lib", ] [tool.uv.sources] models-lib = { workspace = true } [build-system] requires = ["hatchling"] build-backend = "hatchling.build" |
Synchronize the whole workspace :
uv sync --all-packages
All local packages are cross-linked in editable mode inside the root .venv automatically.
Global CLI tools & single-file execution
Install a CLI tool globally in an isolated environment (replaces pipx) :
uv tool install ruff
uv tool install black
uv tool install twine
List installed global tools :
uv tool list
Update or remove global tools :
uv tool update --all
uv tool uninstall ruff
Run an ephemeral tool without installing it (uvx) :
uvx ruff check .
uvx black --check .
Network, proxy and cache management
Use a proxy and custom / trusted index :
uv pip install requests --proxy http://user:pass@myproxy:8080 --default-index https://pypi.org/simple --allow-insecure-host my-internal-host
Clean and prune uv global cache :
uv cache prune (removes outdated / unreferenced packages)
uv cache clean (clears entire cache directory)