Why Monorepos Win for Small Teams (And When They Don't)
Multi-repo is overhead masquerading as separation of concerns. For teams under 50, monorepo is almost always right.
You started with one repo. It got messy. Someone said "we need to split this up for clean boundaries." Now you have 12 repos, three of which are out of sync, and a CI pipeline that takes 40 minutes.
This is the multi-repo trap. It optimizes for an organizational problem you don't have yet at the cost of a velocity problem you have today.
What multi-repo actually costs
Every repo split adds:
- A new CI pipeline to maintain
- Cross-repo PRs for any feature touching both sides
- Version pinning between repos (eventually wrong)
- Onboarding overhead — new hires clone 8 things
- Context switching when debugging — "wait, which repo is the auth code in?"
These costs compound. A two-repo split is fine. A twelve-repo split is a part-time job.
What multi-repo is supposed to give you
The pitch: "clean boundaries, independent deploys, smaller blast radius."
The reality at small scale:
- Boundaries — enforced better by directory structure + linting than by repo lines
- Independent deploys — your monorepo can deploy services independently. CI just needs to know what changed.
- Blast radius — you're going to break things anyway. Fewer repos = less time finding which repo broke
Multi-repo solves a coordination problem between teams that don't talk to each other. If you're under 50 engineers, every team talks to every team. You don't have the problem multi-repo solves.
What monorepo actually gives you
Atomic cross-cutting changes. Renaming an API field touches the backend, the frontend client, and the mobile app in one PR. One review, one merge, one deploy.
Single source of truth for tooling. Same lint config, same test runner, same CI pipeline. Update the config once.
Refactor without fear. "Find every caller of this function" works because there's one tree to grep.
Type sharing. Your TypeScript types, your protobufs, your OpenAPI specs — generated once, consumed everywhere. No drift.
Faster onboarding. git clone, npm install, you have everything.
The "monorepos don't scale" objection
It's true that Google-scale monorepos need custom tooling. You are not Google.
For real-world numbers:
- Up to ~1M lines of code: vanilla
npm/pnpmworkspaces work fine - Up to ~10M lines: add Turborepo or Nx for caching
- Beyond that: you can afford to invest in Bazel
You will likely never get past tier one. Stop pre-optimizing for scale you don't have.
When monorepo is wrong
There are real cases:
- Different languages/runtimes that can't share tooling — Python ML pipeline + Rust backend + Swift iOS, with no shared types. Splitting reduces tooling friction.
- Different security boundaries — open-source SDK that customers see vs. proprietary backend. Don't let internal code leak into public reads.
- Acquired companies — merging codebases is rarely worth the engineering time. Run them in parallel.
- Hard org boundaries — separate companies, contractor work, etc.
If none of these apply, monorepo.
The migration path
You're already in multi-repo hell. Should you consolidate?
Probably yes, but not this quarter. Migration costs:
- Combining git histories (use
git subtreeorlekkonimitti-style merges) - Unifying CI
- Breaking everyone's local dev environment for a week
- Resolving naming conflicts
Do it when you're already touching CI for another reason. Don't do it as a standalone project — that's a hard sell to anyone above you.
The shape that works
/
├── apps/
│ ├── web/ # Next.js
│ ├── api/ # Express/Fastify backend
│ └── mobile/ # React Native
├── packages/
│ ├── shared-types/ # Generated from OpenAPI
│ ├── ui/ # Shared React components
│ └── utils/ # Pure functions
├── infra/
│ └── terraform/
└── package.json # Workspaces root
npm workspaces, pnpm, or yarn workspaces — all work. Add Turborepo when CI gets slow.
The takeaway
Multi-repo is overhead disguised as architecture. For small teams it makes everything harder for benefits you won't realize at your scale. Default to one repo, split only when there's a concrete reason.
Work with me
I consult with engineering teams on AI adoption, cloud architecture, and engineering effectiveness. If this post surfaced a challenge you're facing, let's talk.
Get in touch →Related posts
Explore more on these topics: