The Debate That Won't Die
Every replatforming project eventually hits the repository structure question. Monorepo advocates (Google, Meta, Microsoft) argue for shared tooling, atomic cross-service commits, and unified CI. Multi-repo advocates argue for independent deployments, security isolation, and focused developer experience.
Both camps have valid points. Most advocacy comes from organisations where one set of trade-offs clearly dominates — and smaller teams apply those lessons without adjusting for their context.
The Starting Point: Four Applications
| Application | Technology | Hosting |
| --- | --- | --- |
| Customer-facing website | Next.js 15 | Vercel |
| Core backend API | Express + TypeORM | AWS Lambda |
| External integrations gateway | Express | AWS Lambda |
| Admin panel + ops tools | Next.js + Prisma | Vercel |
These four applications communicate via API. Different hosting platforms. Different deployment triggers. Different tooling requirements.
The Monorepo Case
The strongest arguments for monorepo in this context:
- ·Shared code without package publishing: TypeScript interfaces shared between frontend and backend live in a shared package — no npm publishing required
- ·Atomic cross-service changes: Change a backend API contract and update the frontend in the same commit
- ·Unified developer experience: One clone, one
npm install, unified ESLint and TypeScript config
Why Multi-Repo Won
We evaluated Nx and Turborepo and concluded the benefits don't outweigh the costs at our scale:
Services communicate via API, not shared libraries: The tight coupling that makes atomic commits valuable doesn't exist in our architecture. Frontend and backend have clearly defined API boundaries. Breaking changes are handled through API versioning, not atomic commits.
Different hosting platforms map naturally to different repos: Vercel for frontend, AWS Lambda for backend. These have different CI pipelines, environment variables, and build processes. Monorepo handles this with added complexity that doesn't serve the team.
Monorepo tooling has overhead: Nx and Turborepo are capable tools that the team must learn, configure, and maintain. Affected task computation, build caching, project graph configuration — overhead that doesn't deliver feature value for a team of our size.
CI pipelines become complex: In multi-repo, a PR to the backend runs only backend tests. In monorepo, you need affected task computation to avoid running all tests on every PR — and when it misfires, debugging it is painful.
Security isolation: The external gateway has separate credentials and access controls. Multi-repo means compromising one repo's secrets doesn't compromise all repos.
Solving the Shared Code Problem
For API contracts: A lightweight internal package (@company/api-types) in its own small repository, published to a private registry. The contract between frontend and backend is a versioned API — the types package reflects that.
For shared utilities: Keep these minimal. The temptation to create a shared utilities library creates implicit coupling. If the same utility is needed in two places, that usually signals something belongs in a shared service, not a shared library.
When Monorepo Is the Right Answer
Monorepo clearly wins when:
- ·Frequent cross-service changes: typical features require coordinated changes across 3+ services
- ·Large shared library surface area: 30%+ of code is shared between services
- ·Dedicated platform engineering team: someone owns the build infrastructure
- ·10+ services: consistency benefits outweigh CI complexity
For a four-service platform with a lean team, clear API boundaries, and different hosting platforms — multi-repo is the right choice.
The Practical Decision Test
Three questions:
- 1.How often do you make changes spanning more than one service? If rarely — because your services have clear API contracts — multi-repo is likely right.
- 1.Do you have platform engineering capacity to own monorepo tooling? If no, the overhead lands on the team unexpectedly.
- 1.Are your services deployed to the same platform? If your frontend goes to Vercel and backend to AWS, the tooling divergence argues for repo divergence.
There is no universally right answer. There's only the right answer for your team, codebase, and deployment context.