Monorepo vs polyrepo for micro-frontends
Micro-frontends are about independent deployment. Where the code lives is a separate decision. A monorepo and one repository per team can both work, with different costs.
Two decisions that get mixed up
A common assumption is that micro-frontends require one repository per team. They do not. A micro-frontend is defined by being built and deployed independently. That can be done from a single repository, as long as the pipeline builds and releases only what changed.
The repository question is about something else: how code is shared, how dependencies are upgraded and how much autonomy each team has over its tools.
Monorepo
The host, all remotes and the shared libraries live in one repository. Nx is a common choice for this in the Angular world.
What you get
- One version of each dependency. A single
package.jsonand lockfile means every remote uses the same Angular version. Shared singletons at runtime are simple because there is nothing to align. - Atomic changes. A change to a shared library and to the remotes that use it goes in one pull request.
- Easy code sharing. A shared library is a folder. No publishing, no version bump.
- Enforced boundaries. Nx lint rules can forbid imports between areas, so a remote cannot reach into another remote's code.
- Affected builds and caching. Nx computes which projects a change touches and builds and tests only those.
What it costs
- Upgrades are for everyone at once. A framework upgrade is one large change that all teams absorb together. That is efficient when it goes well and blocking when one area is hard to upgrade.
- CI depends on the tooling. Without affected commands and caching, pipeline time grows with the repository. Someone has to own that setup.
- Sharing is too easy. When importing from another area costs nothing, coupling grows unless the boundary rules are strict.
- Independent releases need discipline. The pipeline must deploy only the affected remotes. If every merge releases everything, you have a monolith with extra steps.
Polyrepo
Each team has its own repository for its remote. The host and the shared libraries have theirs.
What you get
- Full autonomy. Each team chooses when to upgrade and how to structure its pipeline, inside the platform's rules.
- Clear ownership. The repository boundary is the team boundary. Permissions, reviews and history are simple.
- Independent upgrades. One area can move to a new framework version while another waits, within what the shared dependency rules allow.
What it costs
- Shared code becomes packages. The design system, the contract types and any utilities must be published and versioned. Every change is a release followed by upgrades in each consumer.
- Version drift. Without active effort, remotes end up on different versions of the framework and the design system. At runtime that means duplicated code or load errors. See shared dependencies and versions.
- Duplicated configuration. Build setup, lint rules and pipeline definitions are copied and then diverge. Templates and generators reduce this.
- Slow cross-cutting changes. A change that touches all remotes needs one pull request per repository and someone to chase them.
Side by side
| Criterion | Monorepo (Nx) | Polyrepo |
|---|---|---|
| Independent deployment | Possible, needs an affected-only pipeline | Natural |
| Dependency versions | One version, always aligned | Per repository, drift by default |
| Sharing code | Direct import of a library | Published packages |
| Framework upgrades | One coordinated change | Per team, at different times |
| Team autonomy over tooling | Low | High |
| CI time | Depends on caching and affected builds | Small per repository |
| Cross-cutting changes | One pull request | Many pull requests |
| Risk of hidden coupling | Higher, controlled with boundary rules | Lower |
How to choose
- Choose a monorepo if the teams belong to one organization, use the same framework, and you want version alignment to be automatic.
- Choose polyrepo if teams are far apart, for example different business units or vendors, or if they need different release rules or technology stacks. It also fits when one area is legacy and will stay on an old stack for a long time.
- A middle path is common: one monorepo per large domain or department, with the design system and the contract published as packages between them.
Whatever you pick, automate dependency updates. A tool such as Renovate opens upgrade pull requests in every repository, which is the main defense against drift in a polyrepo.
The repository model can change later. The runtime contract between host and remotes is the same in both models. If that contract is clean, moving a remote into or out of a monorepo is a tooling task. Pipeline design for both models is covered in CI/CD for micro-frontends, and team boundaries in team ownership and Conway's law.
More in this section
- From frontend monolith to micro-frontends, step by step
- Running a legacy AngularJS app inside a micro-frontend host
- Team ownership, boundaries and Conway's law
- The real cost of micro-frontends
Planning a migration or a micro-frontend platform?
In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.
Message me on LinkedIn