Mastering Python Monorepos with uv Workspaces
Overview: The Monorepo Challenge
Managing multiple Python applications within a single repository often leads to a "dependency hell" of local virtual environments and duplicated logic.

Prerequisites
To follow this guide, you should have a solid grasp of pyproject.toml configuration. You should also have
Key Libraries & Tools
- uv: An extremely fast Python package and project manager.
- FastAPI: A modern web framework for building APIs.
- Typer: A library for creating CLI applications.
- OpenAI: Used here for summarizing text via GPT models.
- httpx&Beautiful Soup: Tools for web requests and HTML parsing.
Code Walkthrough: Configuring the Workspace
1. Root Configuration
In the project root, create a pyproject.toml that defines the workspace members. This tells uv which directories to treat as part of the collective environment.
[project]
name = "my-monorepo"
version = "0.1.0"
dependencies = ["python-dotenv"]
[tool.uv.workspace]
members = ["packages/*"]
2. Defining Local Sources
To import an internal package (e.g., core) without publishing it to PyPI, use the tool.uv.sources table. This points uv to the local file path.
[tool.uv.sources]
core = { workspace = true }
3. Syncing the Environment
Run the following command at the root to create a single .venv that encompasses all dependencies for every package in the workspace:
uv sync
Syntax Notes: The Workspace Source Pattern
The workspace = true flag is a specific uv convention. It ensures that when you run uv sync or uv run, the tool looks internally for the dependency rather than searching the public registry. This allows for seamless cross-package imports like from core.news import fetch_headlines across different applications.
Practical Examples
Consider an automation repo containing dozens of small scripts. Instead of each script having its own httpx version, they all draw from the workspace root. When you update a shared accounting layer in a core package, every web-hook listener and data-extraction tool in the repository immediately benefits from the update without manual re-installs.
Tips & Gotchas
- VS Code Support: Sometimes the IDE struggles with workspace-level imports. Selecting the root virtual environment as your Python interpreter usually resolves type-checking issues.
- When to Avoid: If your apps are completely unrelated or you intend to release a package independently on PyPI, separate repositories remain the better choice. Workspaces thrive on high overlap and shared context.