Monorepo vs Polyrepo: Which Should You Choose
A monorepo holds all projects in one repository; a polyrepo splits them apart. Trade-offs in tooling, ownership, and CI/CD for each approach.
A monorepo stores multiple projects — services, libraries, apps — in a single Git repository with shared tooling and a unified commit history. A polyrepo splits each project into its own repository with independent versioning, permissions, and release cycles. Both are viable ways to organize a codebase at scale; the right choice depends less on project count and more on how tightly your teams and services actually need to coordinate.
What a monorepo looks like in practice
In a monorepo, frontend/, backend/, and shared-lib/ might all live as directories under one repository root, sharing a single .git history. A change to shared-lib and the two consumers that depend on it can land in one atomic commit, reviewed in one pull request. Large organizations running monorepos typically pair them with specialized build tooling — incremental build systems that only rebuild and retest what actually changed, since a naive full rebuild on every commit doesn’t scale once a repository holds hundreds of projects.
What a polyrepo looks like in practice
In a polyrepo setup, frontend, backend, and shared-lib each get their own repository, their own CI pipeline, and their own release cadence. shared-lib gets versioned and published as a package; frontend and backend declare a dependency on a specific version and upgrade on their own schedule. This is the default structure most projects fall into organically — one repo per service is the path of least resistance, especially for teams already used to semantic versioning and package registries.
Comparing the two
| Monorepo | Polyrepo | |
|---|---|---|
| Cross-project changes | One atomic commit, one PR | Coordinated changes across multiple PRs and releases |
| Dependency versions | Usually one version of each shared library, used everywhere | Each project pins its own version, can drift |
| CI/CD | Needs tooling to build/test only what changed | Naturally scoped — each repo’s pipeline only sees its own code |
| Access control | Coarser — often repo-wide, needs extra tooling for path-level permissions | Fine-grained by default — one repo per team or service |
| Discoverability | Easy to search and refactor across the whole codebase | Requires cross-repo search tooling |
| Tooling investment | High — needs a build system that scales with repo size | Low — standard per-project tooling works fine |
| Onboarding | Clone one repo, see everything | Clone many repos, harder to see the whole picture |
The case for a monorepo
The strongest argument for a monorepo is atomic cross-cutting changes. If shared-lib changes its API and three services need to update in lockstep, a monorepo lets that happen in one commit with one CI run verifying all of it together. In a polyrepo, the same change means publishing a new version of shared-lib, then opening three separate PRs to bump the dependency in each consumer, with a window where they’re out of sync.
Monorepos also make refactoring at scale and code search easier — a rename or a security fix that needs to touch every consumer of a function is a single find-and-replace plus one CI run, not a coordinated rollout across a dozen repositories. This is one reason monorepos are popular for organizations doing heavy internal platform engineering, where shared libraries change often and need to propagate quickly; see platform engineering and internal developer platforms for the broader context this fits into.
The case for a polyrepo
The strongest argument for a polyrepo is isolation. A broken build in one repository doesn’t block CI for every other team. Access control is naturally scoped — a contractor or partner team can get access to exactly one repo without complex path-based permission rules. And polyrepos need essentially no specialized tooling: standard CI/CD, standard package managers, and standard semantic versioning work out of the box, whereas monorepos at any real scale need investment in incremental build and test tooling to avoid CI runs that rebuild the entire codebase for every change.
Polyrepos also map more naturally onto team boundaries when teams are genuinely independent — different release cadences, different CI/CD requirements, different compliance scopes.
What actually drives the decision
The deciding factor is less “how many projects do we have” and more “how coupled are they.” A set of services that share a lot of code, deploy together, and are maintained by overlapping teams benefits from a monorepo’s atomicity. A set of services that are independently owned, versioned, and deployed — even if they occasionally call each other over an API — often works better as separate repositories, since a shared repo would mostly just add coordination overhead without adding real benefit.
Team size and organizational structure matter too. Monorepos work well when there’s a platform or infrastructure team maintaining the shared tooling that makes scale bearable; without that investment, a monorepo can turn into a repository nobody wants to touch because CI takes twenty minutes and any change risks breaking someone else’s project.
The takeaway
A monorepo trades tooling investment for atomic cross-project changes, unified dependency versions, and easier large-scale refactoring. A polyrepo trades some coordination overhead for isolation, simpler tooling, and natural team-scoped access control. Neither is universally correct — match the choice to how coupled your projects actually are and whether you have (or are willing to build) the tooling a monorepo needs to stay fast at scale.
Tagged
Keep reading
The Lycoris Team · · 4 min read Distributed Tracing Explained: Following Requests Across Services
Distributed tracing follows a single request as it crosses service boundaries, using spans and trace IDs to reconstruct the full call path and find where time goes.
Chisato · · 5 min read Logs vs Metrics vs Traces: The Three Pillars
Logs, metrics, and traces each answer a different question about a running system — what each captures, and how they work together.
Chisato · · 4 min read The Twelve-Factor App Methodology Explained
The twelve-factor app is a set of principles for building portable, scalable cloud software. Each factor explained, and why they still hold up today.