Multirepo
A Multirepo means that each project or component has its own separate repository. This approach enables autonomous teams, independent release cycles, and project isolation.
✅ When is it appropriate
A Multirepo is a good choice if most of the following apply:
- each project or service can be developed, tested, and deployed independently without needing to coordinate with other teams
- each project has its own release cycle and a release in one must not block or require changes in another
- different teams need strict access boundaries so that one team cannot accidentally change code they do not own
- projects use different programming languages, frameworks, or build systems that would conflict if placed in a single repository
- a bug or deployment failure in one project should have no risk of affecting the build or deployment of unrelated projects
A multirepo approach gives each team full ownership of their repository. They can choose their own tooling, set their own release schedule, and deploy without waiting for unrelated changes in other repositories to be ready.
❌ When is it NOT appropriate
A Multirepo may not be ideal if:
- projects are tightly coupled and a change in one almost always requires a simultaneous change in another, making separate repositories hard to keep in sync
- multiple projects share common libraries and keeping those libraries consistent across many repositories is causing repeated, manual update work
- the team is small and managing separate repositories, pipelines, and access rules adds overhead that a single repository would eliminate
- cross-project refactoring is frequent and doing it across many repositories requires opening separate pull requests and coordinating merges one by one
When projects share a lot of code or change together frequently, splitting them across repositories creates synchronisation work that grows with every cross-project change. Each shared library update requires opening pull requests in every repository that depends on it.
👍 Advantages
- each team deploys on their own schedule without waiting for other teams to finish their changes
- independent release cycles mean a breaking change in one service does not force all other services to release at the same time
- a failed pipeline or deployment in one repository has no effect on the pipelines of other repositories
- each repository is small enough that cloning, searching, and building stay fast regardless of how large other repositories grow
- each project can use the programming language, framework, and build tooling that best fits its requirements
- repository access can be granted or restricted per project without complex configuration
👎 Disadvantages
- a change that spans multiple services requires separate pull requests in each repository, and those changes must be merged and deployed in the right order
- each repository duplicates linting configuration, CI pipeline files, and dependency update scripts that could otherwise be maintained once
- each repository needs its own pipeline to maintain, so the total number of pipelines grows as the number of services grows
- moving a function used by several services to a shared library requires updating every dependent repository and releasing a new version before any service can use the change
- when a shared library releases a new version, every dependent repository must open a pull request to update the version reference, or services gradually diverge
🛠️ Typical use cases
- large teams with many autonomous projects
- microservices with independent lifecycles
- projects using different tech stacks
- open-source projects with separate modules that have their own issue trackers, contributors, and release notes
- regulated environments where different projects must be kept separate for compliance or access-control reasons
⚠️ Common mistakes (anti-patterns)
- splitting a single cohesive service into multiple repositories because ownership is unclear, making every feature change require coordinating across several repositories
- not tracking which version of a shared library each service depends on, so services silently diverge and integration failures appear only at deployment time
- copy-pasting CI pipeline files and linting configuration into every repository instead of maintaining a shared template, so fixing a pipeline bug requires updates in dozens of places
- creating a separate repository for every small utility function, resulting in hundreds of tiny repositories that are harder to discover and maintain than a single shared library would be
- not documenting which repositories depend on each other, so developers cannot tell whether updating one service will break consumers in other repositories
The most common failure is splitting repositories before deciding who owns what. When boundaries are unclear, any feature that crosses repositories requires multiple pull requests, multiple code reviews, and careful merge ordering, which slows the team more than a monorepo would have.
💡 How to build on it wisely
Recommended approach:
- Clearly define team ownership and responsibilities.
- Use a dependency bot such as Renovate or Dependabot to automatically open pull requests when a shared library releases a new version, so dependent repositories do not fall behind.
- Create a shared pipeline template that all repositories reuse, so a fix to the CI configuration only needs to be made once and propagates automatically.
- Document integrations between repositories.
- Regularly check for duplication and refactor.
A multirepo is the right choice when teams and their projects are genuinely independent. The signal to reconsider is when cross-repository changes are frequent, shared libraries are diverging because updates are not propagated, or developers routinely have to open and coordinate pull requests in three or more repositories to ship a single feature.
Related topics
☕ If you found this page helpful, consider supporting my work by buying me a coffee.
Feedback & Sharing
Give us your thoughts on this page, or share it with others who may find it useful.
Share with your network:
Feedback
Found this helpful? Let me know what you think or suggest improvements 👉 Contact me.