100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Bash

Monorepos vs Polyrepos

Compare storing all projects in a single monorepo versus many independent polyrepos, and the tradeoffs each makes around tooling, ownership, and history.

GitHub & Team PracticesAdvanced10 min readJul 9, 2026
Analogies

Monorepos vs Polyrepos

A monorepo stores multiple, often independently deployable, projects — services, libraries, frontends — inside a single Git repository with a single unified history. A polyrepo strategy instead gives each project (or even each library) its own repository, its own history, and its own release cadence. Neither is universally correct; the choice trades off atomic cross-project changes, unified tooling, and simpler dependency management against repository size, access-control granularity, and the blast radius of a single misconfiguration. Companies like Google and Meta famously run enormous monorepos with custom tooling built specifically to make Git (or, in Google's case, a purpose-built alternative) scale to that size, while many organizations with more standard needs find polyrepos simpler to reason about and secure.

🏏

Cricket analogy: Choosing monorepo versus polyrepo is like a franchise deciding whether all its age-group teams (U16, U19, senior) share one central academy and coaching staff, or each has its own ground and coaches — the IPL's Mumbai Indians centralizes scouting across teams while others keep academies separate.

What a monorepo buys you

The headline benefit of a monorepo is atomic cross-cutting changes: if a shared library's API changes, every consumer in the repository can be updated in the same commit, reviewed in the same pull request, and merged together — there is no window where a breaking change has shipped to the library but not yet propagated to callers, and no need to coordinate version bumps across repositories. Code search and refactoring tools naturally see the whole codebase at once. Dependency management also simplifies: instead of publishing an internal library to a package registry and bumping version numbers across every consumer, code simply references the library's current path in the same tree. The tradeoff is that repository size, clone time, and CI cost all grow with the whole organization's codebase rather than with one team's slice of it, which is why large-scale monorepos typically require investment in sparse checkouts, build caching, and custom CI that only builds what actually changed.

🏏

Cricket analogy: This is like a team changing its fielding drill standard mid-season — in a monorepo-style setup, every age-group squad updates their drills together in one training session, so no U19 squad is ever left practicing an outdated drill while the seniors have moved on.

What a polyrepo buys you

A polyrepo keeps each project's history, issue tracker, access controls, and release cycle independent. A team can move fast on its own service without CI runs for unrelated projects slowing it down, and permissions can be scoped precisely — a contractor working on one microservice never needs read access to the rest of the organization's code. The cost shows up at integration boundaries: a change to a shared library now requires publishing a new version, and every downstream repository must separately update its dependency version, which can lag for months and produce exactly the kind of version-skew problems monorepos avoid. Coordinating a change that spans several repositories also means opening several pull requests, which cannot be reviewed or merged as one atomic unit — someone has to track that all of them land together, often manually.

🏏

Cricket analogy: A polyrepo is like each franchise running its own separate academy, contract, and season schedule — Chennai Super Kings can move fast on its own roster without waiting on Mumbai Indians' training calendar, but trading a player between them now requires separate negotiations on both sides.

bash
# A monorepo's directory layout typically groups projects, not commit history, by boundary
# repo-root/
#   packages/
#     shared-ui/
#     billing-service/
#     web-app/
#   tools/build-scripts/

# Sparse checkout: only pull the parts of a large monorepo you actually need
git clone --filter=blob:none --sparse https://github.com/acme/monorepo.git
cd monorepo
git sparse-checkout set packages/billing-service packages/shared-ui

# In a polyrepo world, pulling in a shared library update means bumping a version
# package.json in web-app's repo
#   "shared-ui": "^4.2.0"  ->  "^4.3.0"
npm install shared-ui@4.3.0
git commit -am "chore: bump shared-ui to 4.3.0 for new Button variant"

'Monorepo' describes how code is stored, not how it is built or deployed — a monorepo can still produce many independently versioned, independently deployed artifacts. The distinguishing question is whether an atomic commit can span multiple projects, not whether those projects ship together.

Naively cloning a very large monorepo (tens of gigabytes, hundreds of thousands of commits) with a plain 'git clone' can take a prohibitively long time and consume significant disk space. Teams operating at that scale rely on shallow clones, partial clones ('--filter=blob:none'), and sparse-checkout to keep day-to-day work practical — treating a full clone as an exception rather than the default.

A middle ground: many repos, shared tooling

Some organizations land between the extremes: polyrepos for genuine deployment and ownership boundaries, paired with shared tooling (a common CI template, a shared linting config repository, tools like git submodules or subtrees, or a package registry with strict internal versioning discipline) to recover some of a monorepo's coordination benefits without merging everything into one history. There is no single right answer — the decision should follow team topology and how frequently code genuinely needs to change atomically across project boundaries, not a general belief that one approach is inherently superior.

🏏

Cricket analogy: This is like a cricket board keeping each franchise's roster and finances separate (true polyrepo boundaries) while still mandating a shared anti-corruption unit and a common umpiring panel across all franchises, recovering some coordination benefits without merging the franchises into one entity.

  • Monorepos enable atomic cross-project commits and unified tooling but require investment to keep CI and clones fast at scale.
  • Polyrepos give precise access control and independent release cadence but push coordination costs to version bumps across repositories.
  • 'Monorepo' describes storage and history, not deployment — a monorepo can still ship many independently deployed artifacts.
  • Large monorepos typically rely on sparse or partial clones rather than a full clone as the everyday default.
  • Version skew between a shared library and its consumers is a structural risk unique to the polyrepo model.
  • The right choice depends on team topology and how often changes genuinely need to span project boundaries atomically.

Practice what you learned

Was this page helpful?

Topics covered

#Bash#GitVersionControlStudyNotes#SoftwareEngineering#MonoreposVsPolyrepos#Monorepos#Polyrepos#Monorepo#Buys#StudyNotes#SkillVeris