Monorepo vs Multi-repo: A Practical Guide
The monorepo vs multi-repo debate generates strong opinions. Google and Meta use monorepos with millions of files. Many successful companies use multiple repositories. Neither is universally right or wrong.
What matters is understanding the tradeoffs and picking what fits your situation.
What's a Monorepo?
A monorepo is a single repository containing multiple projects, applications, or packages. Your frontend, backend, shared libraries, and infrastructure code might all live in one repo.
This doesn't mean one giant application. It means multiple distinct projects in one version-controlled repository with clear boundaries between them.
The Case for Monorepos
Atomic changes across projects. When you change a shared library, you can update all consumers in the same commit. No coordinating across repos or managing version compatibility.
Easier code sharing. Extracting code into a shared package is trivial when everything's already in one repo. No need to set up a private package registry or manage versioning.
Consistent tooling. One set of linting rules, one test configuration, one CI pipeline that understands everything. Changes to tooling apply everywhere immediately.
Simpler onboarding. New developers clone one repo and have everything. No hunting for documentation about which repos to clone and how they relate.
Easier refactoring. Large refactors that touch multiple projects happen in one branch with one review. You can see the full impact of changes.
The Case for Multi-repo
Clear ownership boundaries. Each repo has clear owners. Teams can make decisions independently without coordinating with everyone else.
Independent release cycles. Services can be versioned and deployed independently. You don't need to think about whether changes in another project affect yours.
Simpler tooling requirements. Standard git and CI tools work fine. No need for specialized monorepo tooling to handle scale.
Smaller scope for changes. Pull requests are naturally scoped to one project. Reviews are simpler because the context is bounded.
Access control. Different repos can have different permissions. Contractors might access one service but not others. Security-sensitive code can be more restricted.
The Tooling Question
Monorepos at scale need special tooling. When you have thousands of packages, you can't run all tests on every commit. You need tools that understand the dependency graph and only test what changed.
Popular monorepo tools:
- Turborepo: Task caching and parallel execution. Good for JavaScript/TypeScript.
- Nx: Similar to Turborepo with more features and framework integrations.
- Bazel: Google's build tool. Powerful but complex. Overkill for most teams.
- Lerna: The original JavaScript monorepo tool. Less actively developed now.
Multi-repo doesn't need special tooling. Standard git workflows work. But you might need tooling for cross-repo coordination: dependency management, synchronized releases, or service discovery.
Team Size and Structure
Small teams often benefit from monorepos. Everyone works closely, code sharing is constant, and coordination overhead is low.
Large organizations with many independent teams might prefer multi-repo. Teams can move at their own pace without stepping on each other. The coordination cost of a monorepo increases with team count.
But this isn't a hard rule. Large companies use monorepos successfully. Small teams use multi-repo successfully. It depends on how your teams actually work.
The Hybrid Approach
Many teams end up somewhere in between:
- One monorepo for closely related services
- Separate repos for unrelated projects
- A monorepo for frontend apps, separate repos for backend services
This pragmatic middle ground gets some benefits of both approaches. Group things that change together, separate things that don't.
Migration Considerations
If you're considering a change:
Multi-repo to monorepo: You'll need to merge git histories, which is possible but tedious. Set up monorepo tooling first. Migrate incrementally, starting with the most closely coupled projects.
Monorepo to multi-repo: Extract projects with their git history using tools like git-filter-repo. Update CI/CD for each new repo. Establish clear versioning for shared code.
Either migration is work. Don't switch just because one approach is trendy. Switch because you're feeling real pain with your current setup.
Questions to Guide Your Decision
How often do changes span multiple projects? If constantly, monorepo makes cross-cutting changes easier.
How independent are your teams? If teams rarely need to coordinate, multi-repo gives them autonomy.
How much do you share code? Heavy code sharing is easier in a monorepo.
What's your tooling budget? Monorepos at scale need investment in tooling and infrastructure.
Do you need fine-grained access control? Multi-repo makes this simpler.
Start Simple
If you're early in a project, a monorepo is often the simpler starting point. You can always split things out later when you feel the need. Starting with multiple repos and merging them later is harder.
But if you already have multiple repos working fine, don't change just for the sake of change. The grass isn't necessarily greener.
It's Not Religion
Both approaches work. Both have tradeoffs. The best choice depends on your specific context: team size, project structure, how often things change together, and how much coordination overhead you're willing to accept.
Don't get caught up in ideology. Use what works for your situation. Be willing to change if your situation changes. The repo structure is a tool, not an identity.