What is a Microfrontend?
Modern frontend applications grow fast. What starts as a clean React app for one team quickly becomes a 200,000-line codebase shared by six teams — with merge conflicts, deployment dependencies, and a codebase that nobody fully understands. Microfrontends exist to solve exactly this.
The monolith problem
A monolithic frontend means one app, one build, one deploy. Every team works in the same repository. Every release ships everything at once. This works well when the team is small and the product is simple.
As teams and product complexity grow, the monolith starts to hurt:
- A bug in the Checkout team's code blocks a Header team release.
- A slow build pipeline means every team waits on every other team.
- Shared global state becomes impossible to reason about.
- Onboarding a new engineer means understanding the entire application.
What is a microfrontend?
A microfrontend is an architectural pattern where a web application is decomposed into smaller, independently deployable frontend applications owned by separate teams.
Each microfrontend is responsible for a distinct domain slice of the UI. A Shell (or Host) application composes them together at runtime or build time.
Key properties of a microfrontend:
- Independent deployability — a team can ship without coordinating with others.
- Technology agnosticism — each MFE can use a different framework (though this is rarely advisable in practice).
- Isolated codebase — teams own their own repository or package.
- Domain ownership — one team owns the UI and the backend for a business domain.
What is a monorepo?
A monorepo is a single version-controlled repository that holds multiple projects or packages. It is often used alongside microfrontends to share common libraries (design systems, utilities, API clients) without publishing to a registry.
A monorepo is not the same as a monolith. A monorepo can contain completely independent applications that are deployed separately.
What a monorepo gives you:
- Atomic cross-project changes — one PR updates the design system and every app that uses it.
- Unified tooling — one ESLint config, one TypeScript config, one CI pipeline.
- Easy code sharing without the overhead of npm publishing.
- Visibility — you can see how every package is used.
How they fit together
Microfrontends solve the deployment and team ownership problem. Monorepos solve the code sharing and tooling consistency problem. They are complementary, not alternatives.
A common setup: multiple applications live in a monorepo, each owned by a separate team, each deployable independently. Nx or Turborepo provides the build orchestration. Webpack Module Federation handles runtime composition.
Server-side vs client-side composition
Microfrontends can be composed in several ways:
Build-time integration — each MFE is an npm package consumed by the shell. Simple, but removes independent deployability since the shell must rebuild when any MFE changes.
Runtime integration via iframes — maximum isolation, but poor UX and no shared state.
Runtime integration via JavaScript — the shell loads remote bundles at runtime. This is what Webpack Module Federation enables. The remote app deploys independently, and the host picks up the new version without a rebuild.
Server-side composition — the server assembles the HTML from multiple service-rendered fragments. Popularised by Zalando's Mosaic and IKEA's approaches.
In practice, Webpack Module Federation with a monorepo is the pattern you'll see at most mid-to-large companies today.
When does this actually matter?
Microfrontends solve real problems, but they introduce real complexity. Before considering them, ask:
- Do we have more than two frontend teams?
- Do those teams deploy independently today?
- Is our app naturally decomposable into distinct UI domains?
If the answer to any of these is no, you do not need microfrontends yet. The next article covers setup — but article 4 covers when not to start at all.