uv Cheatsheet — Workspaces

·Updated March 20th, 2026

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:

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

plaintext
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__.py

Add a Member Inside an Existing Workspace

bash
# Running uv init inside a workspace auto-registers the new member
cd packages
uv init new-lib --lib

uv 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:

toml
# 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

bash
# 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 -- pytest

Workspace Locking

bash
# Lock the entire workspace at once
uv lock

# Check consistency
uv lock --check

The 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.