Should You Use a Monorepo
12 Mar 2026A monorepo is not a strategy. It is a build system decision disguised as a philosophy. For a team of two to ten, the question is not “monorepo or polyrepo” — it is “how much tooling am I willing to run to avoid a git clone.”
What a monorepo actually buys you
One PR touches the API and the frontend that consumes it. One commit. One CI run. No coordinating two merges, no “deploy the backend first” Slack message, no version-pinning a shared package while you wait for a release.
Atomic changes across boundaries are the entire pitch. Everything else — shared tooling, one linter config, “discoverability” — you can get from a good README and a shared eslint config published to a private registry. You don’t need Nx or Turborepo for that.
What it costs you
- CI gets slower unless you build the tooling. Push a one-line change to a shared util and, without path-based filtering, you rebuild and retest everything downstream. Turborepo, Nx, or Bazel exist to solve exactly this, and each is a real thing to learn and maintain.
- Git gets bigger. Ten repos, ten small histories. One repo, one history that keeps growing.
git clonegets slower,git blamegets noisier, andgit logon a single service is polluted with commits from three other services. - Permissions get harder. If you ever need one team or one contractor to see only part of the codebase, a monorepo makes that awkward. Polyrepos give you that for free at the repo boundary.
- Deploys need untangling. A monorepo doesn’t deploy atomically just because it commits atomically. You still need per-service build and deploy pipelines, which means path filtering in CI either way.
The actual tradeoff, sized for you
| Monorepo | Polyrepo | |
|---|---|---|
| Cross-service PRs | One commit | Two PRs, manual coordination |
| CI setup | Needs path filtering or a build tool | Trivial, one pipeline per repo |
| Shared code | Import directly | Publish a package, bump versions |
| Onboarding | Clone once, see everything | Clone what you touch |
| Team growth | Gets harder past ~15-20 engineers without tooling investment | Scales by adding repos |
The verdict for two to ten people
Use a monorepo if your services are genuinely coupled — a frontend and the API it exclusively talks to, a handful of packages that always ship together. Skip the build tool at first. npm/pnpm workspaces or a plain Go module with subpackages handles ten packages fine. You don’t need Nx until your CI runs take more than a few minutes and you’re rebuilding things that didn’t change.
Use separate repos if your “shared” code is actually independent services with their own release cadence — a public API, a background worker, a mobile app. Coupling their git history doesn’t make them less independent; it just makes the repo bigger for no benefit.
The trap to avoid
Don’t adopt a monorepo because a 500-person company’s engineering blog said to. Google and Meta run monorepos because they have the platform teams to make CI fast at that scale — dedicated build engineers, custom remote caching, sometimes custom source control. You have neither problem. Your CI run takes ninety seconds either way.
If you’re already on a polyrepo setup and it’s working, the itch to consolidate into a monorepo is usually not a technical need. It’s a desire for one PR to fix one problem instead of two. That’s a real convenience. Weigh it against the CI slowdown and the loss of clean permission boundaries before you spend a weekend migrating.
Pick based on how often you actually need atomic cross-service changes. If it’s more than once a week, monorepo. If it’s rare, don’t pay the tooling tax for it.