uv Cheatsheet — Workspaces
What Are Workspaces?
Workspaces let you manage multiple interconnected Python packages in a single repository with a single lockfile. This is inspired by Cargo (Rust) and ensures all packages operate with a consistent set of dependency versions.
Good use-cases: a core library + CLI wrapper, a library + plugin system, or a monorepo with shared utilities.
Create a Workspace
Add a [tool.uv.workspace] table to the root pyproject.toml:
[project]
name = "my-monorepo"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[tool.uv.workspace]
members = ["packages/*"]
exclude = ["packages/experimental"]Both members and exclude accept glob patterns and explicit paths.
Typical Layout
my-monorepo/
├── pyproject.toml # workspace root
├── uv.lock # shared lockfile
├── src/
│ └── my_monorepo/
│ └── __init__.py
└── packages/
├── core/
│ ├── pyproject.toml # member
│ └── src/
│ └── core/
│ └── __init__.py
└── cli/
├── pyproject.toml # member
└── src/
└── cli/
└── __init__.pyAdd a Member Inside an Existing Workspace
# Running uv init inside a workspace auto-registers the new member
cd packages
uv init new-lib --libuv will automatically add it to the members list (or it matches an existing glob).
Inter-Package Dependencies
A workspace member can depend on another member:
# packages/cli/pyproject.toml
[project]
name = "cli"
version = "0.1.0"
dependencies = ["core"]
[tool.uv.sources]
core = { workspace = true }Run Commands in a Specific Member
# From anywhere in the workspace
uv run --package cli -- python -m cli
uv sync --package core
# Or cd into the member directory
cd packages/core
uv run -- pytestWorkspace Locking
# Lock the entire workspace at once
uv lock
# Check consistency
uv lock --checkThe lockfile is always workspace-wide. You cannot lock individual members separately.
Shared Configuration
Configuration in the workspace root’s [tool.uv] applies to all members. Individual members can override [tool.uv.sources] — if a member defines a source for a dependency, it takes precedence over the root’s source for that same dependency.
When Not to Use Workspaces
Workspaces are not suited for members with conflicting dependency requirements (e.g., one needs numpy==1.x and another needs numpy==2.x). Since there’s a single lockfile, all members must agree on versions. Use separate projects instead, or declare conflicting extras.