Monorepos vs Polyrepos

Updated

October 30, 2026

Monorepos vs Polyrepos

After this page you can place desk-web, desk-api, and desk-infra in one Git repository or three, on purpose.

Polyrepo (this book’s default so far)

Three repositories, three histories, three remotes:

~/desk/desk-web
~/desk/desk-api
~/desk/desk-infra

Each clones, branches, and CI-runs on its own. A change that spans API and web is two pull requests. Versions of each other are documented (“web 1.2 needs api 1.4”) or ignored until something breaks.

Monorepo

One repository:

~/desk/desk/
  web/
  api/
  infra/

One git clone, one main, one PR can touch all three. CI must learn to run only what changed, or it becomes slow. Sparse checkout and partial clone (chapter 19) exist because monorepos grow.

Trade-offs

Monorepo Polyrepo
Cross-project change One PR Several PRs, several versions
Access control One repo (paths, CODEOWNERS) Separate remotes, easier per-team ACLs
CI Must be smart or it is slow Simple per repo
Submodules Rarely needed Common for shared libs
Git scale Packfiles, sparse, LFS Each repo stays small

Linux tooling

Path-based CI (git diff --name-only origin/main...HEAD | grep '^api/') is how a monorepo stays fast. CODEOWNERS (chapter 31) assigns api/ to one team. None of that requires GitHub; the files are in Git.

This book

Labs keep three polyrepos so platform chapters can push desk-api to GitLab and Forgejo independently. If your real desk is a monorepo, the Git commands are the same; only the directory layout changes. Worktrees still apply. Submodules usually do not.