Table of contents
- What is a monorepo?
- Why teams choose (or avoid) monorepos
- When to use monorepos (with clear examples)
- When not to use a monorepo
- Monorepo best practices
- Introducing Graphite and PR stacking
- Final thoughts
What is a monorepo?
A monorepo (short for monolithic repository) is a single version‑control repository holding many related—or even independent—projects. Unlike a monolithic architecture, a monorepo doesn't force all projects to be tightly coupled or deployed together. It simply centralizes code. Big companies like Google, Facebook, Microsoft, and Airbnb use them to simplify dependency management, enable atomic commits across services, and foster cross‑team collaboration.
Why teams choose (or avoid) monorepos
Benefits
Atomic cross‑project changes You can update a shared service and all its clients in one commit, simplifying evolution.
Centralized dependency control Avoid version mismatches: every module can share the same dependency versions.
Simplified code sharing and visibility Developers can discover and reuse libraries more easily.
Challenges
Scaling tooling and infrastructure Without tools like Bazel, Pants, Nx, or Turborepo, builds and tests slow to a crawl.
Merge conflicts and CI complexity Many teams contributing can collide on files and test pipelines.
Access control and clone‑size issues Giving full access to everyone and requiring massive checkouts may conflict with security or resource constraints.
When to use monorepos (with clear examples)
Scenario | Why monorepo fits |
---|---|
Tightly coupled tools/libraries | E.g., frontend UI components and backend APIs intended to evolve together—atomic version updates are essential. |
High code reuse across teams | Shared utilities or internal SDKs are easier accessed and updated directly. |
Small (<20 devs) or mega (>500 devs) teams | Avoids multi‑repo overhead for small teams; mega‑teams can invest in build infrastructure. |
When not to use a monorepo
A monorepo may not be the right choice if your projects are loosely coupled or involve third-party deliverables that require separate release cycles. It can also be a poor fit for small teams that lack mature CI/CD processes and may be overwhelmed by the operational overhead. Additionally, if your components require stringent access controls or you need especially lightweight tooling, a monorepo's centralized approach could introduce unnecessary complexity or security concerns.
Monorepo best practices
Adopt scalable build tooling
Use tools like Bazel, Pants, Nx, Turborepo, or Lerna + Yarn Workspaces to enable incremental builds and fast CI/CD.
Modular monorepo layout
Organize code into apps/
for services and packages/
for shared modules.
Incremental CI and test pipelines
Configure your CI to build and test only the changed folders, not the entire monorepo—use affected‑target detection strategies.
Merge queues for stability
Use merge queue systems that batch, re‑test, and merge stacked PRs in order to keep the main branch green.
Introducing Graphite and PR stacking
Graphite enables stacked pull requests, a workflow specifically designed for monorepos. With Graphite, you can:
- Break down large features into ordered, incremental, and dependent PRs.
- Allow reviewers to handle PRs incrementally, significantly reducing review fatigue.
- Automate your merge queue to rebase, test, and merge PRs seamlessly in the correct order.
This workflow fits naturally with monorepo requirements, enabling atomic cross-project changes, precise test triggering, reduced merge conflicts, and accelerated feedback loops.
Final thoughts
- Opt for a monorepo if your code is interdependent, needs shared libraries, or benefits from coordinated atomic changes—and you're ready to invest in build tooling and CI discipline.
- Avoid it if your modules are independent products, require strict isolation, or your team lacks CI maturity.
- Pair monorepos with Graphite to harness stacked PRs, merge queue, and stronger CI workflows—making scaled collaboration more reliable and efficient.