Live · Fri, Sep 4, 2026 · 05:01 UTC Block 843,917 Fees 14 sat/vB Fear & Greed 72 · Greed
Newsletter Pro Terminal Sign in
ITop Field News.
Subscribe →
Live · 05:01 UTC Block 843,917 F&G 72
Software development Software development desk

Monorepo vs polyrepo: which structure fits your team?

Monorepo vs polyrepo is a decision that shapes how your team ships, reviews, and scales code for years. Here is a practical breakdown of when each structure earns its place.

Two men analyzing code on computers in a modern office setting.

Photo by Mikhail Nilov on Pexels

Monorepo vs polyrepo sits quietly beneath most of the other decisions a development team makes about tooling, CI/CD, code review, and dependency management. Choose wrong and you don't feel it on day one. You feel it eighteen months later, when a shared component update breaks six separate services and nobody is entirely sure who owns the fix.

This isn't an abstract architecture debate. It's a question about how your team actually works: how often people collaborate across services, how mature your tooling is, and how much coordination overhead you can absorb. Both models work. Both break in specific ways under specific conditions.

What each model actually is

A monorepo stores all of a team's code (or all code for a product area) in a single version-controlled repository. Separate projects, services, and libraries live in subdirectories, all versioned together. A polyrepo splits each service or library into its own repository, with its own version history, CI configuration, and access controls.

The terms get blurred. A company running 3 repositories for 3 products isn't really doing polyrepo in any meaningful sense. The model matters when teams are large enough that the number of repos or the shared surface area creates real coordination cost.

The case for monorepos

Atomic commits across services are the strongest argument. When a shared library changes its API, a monorepo lets you update every caller in a single commit. Reviewers see the whole blast radius at once. Nothing ships in an inconsistent state.

Code discovery is dramatically simpler. A developer onboarding into a monorepo can search the entire codebase with one query. Shared utilities don't get silently duplicated because the other team never knew they existed. This matters most for teams doing cross-cutting work: platform engineering, security tooling, or design systems.

Tooling at scale, though, is where monorepos get expensive. Nx, Bazel, and Turborepo all exist because vanilla Git and standard CI runners collapse under the weight of a large monorepo. Build times balloon. Test runs become slow unless you invest heavily in caching and incremental pipelines. CI/CD pipelines that work fine at 50,000 lines of code can take 40 minutes to run at 2 million without careful configuration of affected-only test strategies.

Google, Meta, and Atlassian all run monorepos. That's often cited as validation. It isn't. Those companies built specialised internal tooling for years before their monorepos scaled. What works at Google's engineering headcount doesn't transplant cleanly to a 12-person Australian startup.

The case for polyrepos

Polyrepos are the default for a reason. Every new service gets its own repository, its own pipeline, and its own deployment cadence with no coordination required. Teams own their code completely. An outage in one service doesn't require touching anything else's repository.

Access control is cleaner. Contractors working on a single service see only that service's code. Compliance requirements around data handling become easier to enforce when sensitive code lives in its own isolated repository with its own audit log.

The cost is cross-service changes. When a shared type definition changes, you update one repository, publish a new package version, then open pull requests across every repository that depends on it. Each one goes through its own review cycle. In practice, teams avoid this work, which means shared dependencies drift. A library that was pinned at version 2.1 in five separate services three years ago will still be at 2.1 today, because nobody wanted to coordinate the upgrades.

Dependency drift is polyrepo's slow poison. It's rarely catastrophic on its own. It compounds. Security patches don't get applied. Breaking changes accumulate. Eventually, upgrading anything becomes a multi-week project.

What the decision actually hinges on

Team size matters less than coupling. If your services share significant amounts of code, a monorepo reduces the coordination overhead of keeping that shared code consistent. If your services are genuinely independent with clean API boundaries and no shared business logic, a polyrepo is simpler and imposes less tooling investment.

Your Git branching strategy also shapes the decision. Trunk-based development pairs naturally with monorepos: a single main branch, short-lived feature branches, and fast integration. Long-lived branches and release trains work better with polyrepos, where each service manages its own release lifecycle independently.

Consider the ownership model honestly. Monorepos work best when a team is willing to review and merge code across service boundaries. If your culture is strictly "you own your service, I own mine," a monorepo creates friction without delivering the collaboration benefits that justify it.

Hybrid approaches teams actually use

Most medium-sized Australian dev teams end up somewhere between the two models. A common pattern: one repository per domain (not per service), with shared infrastructure and platform code in a dedicated monorepo. Individual product teams get their own polyrepos but consume platform tooling from a single source.

Another approach is a "meta-repo": a repository of repositories, using tools like Nx to orchestrate builds and dependency graphs across multiple repositories that are separately versioned but co-managed. It carries complexity, but it avoids forcing a binary choice.

The hybrid approach works when you're honest about what you're optimising for. If you want atomic cross-service changes, go monorepo. If you want service independence and simpler access control, go polyrepo. A hybrid that tries to get both often delivers neither.

Tooling requirements by model

Polyrepos need a dependency management strategy from day one. Private package registries (Artifactory, GitHub Packages, AWS CodeArtifact) centralise shared libraries. Automated dependency update tools like Renovate or Dependabot help keep version drift under control, but they require someone to review and merge the pull requests they generate.

Monorepos need build orchestration. Without a tool like Bazel, Turborepo, or Nx, every CI run rebuilds and retests everything. At scale, that's untenable. These tools track dependency graphs and run only the tests affected by a given change. They work well when the dependency graph is accurate and badly when it isn't, so maintaining that graph becomes ongoing engineering work in itself.

Making the call

Start with polyrepo if your team is small (under 15 engineers), your services have clean boundaries, and you don't have shared business logic that cuts across multiple services. The tooling investment for a monorepo won't pay off at that scale.

Consider a monorepo if you have significant shared code, frequent cross-service changes, and the engineering capacity to invest in build tooling. The investment is real. An underpowered monorepo with no caching strategy and a naive CI configuration is actively worse than a polyrepo.

And if you're considering a switch from one to the other: the migration is painful in both directions. Converting a polyrepo to a monorepo requires reconciling divergent histories and agreeing on a single directory structure. Going the other way means splitting history and establishing clean API contracts for everything that was previously shared by reference. Neither migration gets easier by delaying it.

→ The Confirmations · Daily newsletter

One email at 06:00 UTC. Six minutes. The only digest written for desks, not for retail.