Monorepo vs. Polyrepo

Monorepo: all your code in one repository. Polyrepo: code split across many repositories.

Both work. Both have failure modes. The choice has more impact than expected.

The trade-offs

Monorepo

**Pros**:

- Atomic cross-project changes

- Shared tooling (one CI config, one build, one set of dependencies)

- Easy code sharing

- Consistent practices

- One place to look

**Cons**:

- Scaling git operations (clone, status, log)

- Build tools that handle the size

- Permission model (everyone sees everything)

- CI complexity (run only affected tests)

Polyrepo

**Pros**:

- Repository-scoped permissions

- Independent deployment cadences

- Smaller checkouts

- Tool ecosystem is simpler

**Cons**:

- Cross-repo changes require coordination

- Code duplication or shared libraries

- Inconsistent practices across repos

- Versioning shared dependencies is painful

When monorepo wins

- Large organization with extensive code sharing

- Tight coupling between services

- Infrastructure/platform teams that need atomic changes

- Strong tooling investment available

- Teams prefer consistency over autonomy

Famous examples: Google, Meta, Microsoft Office, Twitter (now X) — all run massive monorepos.

When polyrepo wins

- Independent teams owning independent services

- Open-source projects with separate licensing

- External contractors with limited scope

- Smaller orgs without monorepo tooling investment

- Teams want autonomy

Most open-source projects are polyrepo (each library has its own repo). Most startups start polyrepo.

The tooling problem

Monorepos at scale need specific tools:

Build systems

Make/Maven/Gradle work but slow on large monorepos. Tools designed for scale:

- **Bazel** (Google): hermetic, content-addressed, incremental

- **Buck** (Meta): similar to Bazel

- **Pants**: Python-focused; similar concepts

- **Nx** (TypeScript): JavaScript/TS monorepos

- **Turborepo**: simpler; for Node-heavy projects

These tools rebuild only what changed; cache across users; scale to thousands of modules.

Git scaling

For very large repos:

- Shallow clones

- Partial clones

- Sparse checkouts

- Git LFS for large files

Microsoft's Scalar and Git's own improvements have made large monorepos more practical.

CI

Running all tests on every change doesn't scale. Need:

- Affected-detection: which tests depend on changed files

- Caching: don't rebuild what hasn't changed

- Distributed: parallel across many machines

Bazel and similar tools provide this; CI systems integrate.

Code ownership

`CODEOWNERS` files (GitHub native) or similar. Different teams own different paths; PRs route to right reviewers.

Hybrid approaches

Small set of large repos

Not one monorepo, not many small ones. Maybe 5-10 repos for major systems. Each is a "small monorepo."

Multi-repo with shared libraries

Polyrepo with conventions: shared lib repos, service repos, deployment repos. Independent but coordinated.

Repo per language

Each language gets its own repo. Polyglot orgs sometimes do this.

"Modern monorepo"

JS-heavy projects use Nx or Turborepo as a "monorepo lite" — works at most company scales without going to Bazel.

The cultural side

Monorepo vs. polyrepo isn't just technical. It shapes how teams work:

Monorepo culture

- "We see each other's code"

- Cross-team contributions easier

- Shared standards more enforceable

- Stronger central platform

Polyrepo culture

- "My repo, my rules"

- Team autonomy

- Diverse practices

- Service-oriented thinking

Neither is universally better. Match the structure to how you want teams to operate.

Migration

Switching is hard:

Polyrepo → Monorepo

Combine repos one at a time. Use git subtree or git filter-repo to preserve history. Re-tool CI.

Monorepo → Polyrepo

Extract services. Each becomes its own repo with relevant history.

Both migrations take months. Don't switch lightly.

Common failure patterns

- **Monorepo without tooling.** Slow builds; long CI; team frustration.

- **Polyrepo without coordination.** Drift; duplicated effort; cross-repo changes painful.

- **Choosing based on others' choices.** Google has monorepo; doesn't mean you should.

- **Switching strategies repeatedly.** Each migration is expensive.

- **Heavy build system for small org.** Bazel for 10 engineers is overkill.

A reasonable starter position

For new orgs:

- Small (<20 engineers): polyrepo, simple

- Medium (20-200 engineers): hybrid — small set of larger repos

- Large (200+ engineers, lots of sharing): monorepo with proper tooling

Re-evaluate as you grow. The right answer at 10 engineers may not be right at 100.

Further Reading

- [GitWorkflows](GitWorkflows) — Workflow within either

- [CiCdPipelines](CiCdPipelines) — CI strategies differ

- [JavaBuildToolComparison](JavaBuildToolComparison) — Tools at different scales

- [DevOpsAndSre Hub](DevOpsAndSreHub) — Cluster index