Micro-Frontends: Architecture, Composition and Trade-offs

Micro-frontends explained: splitting a web app by team, build-time vs runtime composition, module federation, shared dependencies and when to avoid them.

Advanced 3 min read · Updated

Micro-frontends split a large web application into smaller frontend pieces owned and deployed independently by different teams, then compose them into one experience for the user. A checkout team might own the cart and payment pages while a discovery team owns search and product pages. It's the frontend version of microservices, and it solves the same organisational problem, many teams blocked on one codebase and one release, at a similar cost in complexity.

When they make sense

  • Many teams (often dozens of engineers or more) work on one product and step on each other in a single repository and release.
  • Clear domain boundaries exist, such as search, product, cart, account, so pieces can be owned end to end.
  • Independent deployment matters: teams need to ship on their own schedule without coordinating a global release.
  • Gradual migration: replacing a legacy frontend piece by piece.

For one or two teams, micro-frontends usually cost more than they save. A well-structured monolith with clear modules and good CI is simpler and faster. See monolith vs microservices.

Composition approaches

ApproachHowProsCons
Route-based (separate apps)Each team owns whole pages; links or a reverse proxy route between themStrong isolation, simplestFull page loads between areas; shared header and state duplicated
Build-time integrationTeams publish packages that a container app imports and buildsOne optimised bundle, simple runtimeNot independently deployable: every change needs a container rebuild
Runtime integration (module federation)The container loads remote modules from each team's deployed bundle at runtimeIndependent deploys, shared dependenciesVersion coupling at runtime, harder debugging
Server-side compositionA server or edge layer assembles HTML fragments from team servicesFast first paint, SEO-friendlyInfrastructure complexity, coordinated caching
Web components / iframesEach piece is a custom element or iframeFramework-agnostic, strong isolation (iframes)Iframes hurt UX and accessibility; web components need careful styling and state
BrowserShell applayout · routing · authSearch MFEteam A · own deployProduct MFEteam B · own deployCart MFEteam C · own deployDesign systemshared components
Runtime composition: a shell app owns layout, routing and shared services, and loads each team's micro-frontend from its own deployment.

The hard parts

  • Consistent look and feel: a shared design system, distributed as versioned components and tokens, keeps pieces from diverging.
  • Shared dependencies: loading three copies of a framework kills performance; share libraries as singletons with agreed version ranges, and budget bundle sizes. See Core Web Vitals.
  • Communication between pieces: keep it minimal and explicit, through the URL, custom events or a tiny shared event bus, not a shared global store that couples teams again.
  • Shared concerns: authentication, routing, analytics, error tracking and feature flags belong to the shell or shared libraries.
  • Failure isolation: one micro-frontend failing to load should show a fallback in its area, not a blank page.
  • Testing: contract tests between shell and pieces, plus end-to-end tests of critical journeys across them.

Ownership and governance

Micro-frontends work when each team owns a slice vertically: its UI, its backend-for-frontend or APIs, and its data. A platform or core team owns the shell, design system, build tooling and performance budgets, and sets a small number of rules every piece must follow. Without that, independence turns into inconsistency.

Where it’s used

Large e-commerce sites

Search, product, cart and account pages are owned and deployed by separate teams behind one shell.

Enterprise dashboards

Product teams contribute modules to a shared admin portal, loaded at runtime.

Legacy migration

New micro-frontends replace parts of an old application route by route.

In an interview

  • Justify micro-frontends by team scale and domain boundaries, or argue against them.
  • Compare route-based, build-time, runtime and server-side composition.
  • Address shared dependencies, design consistency and communication.
  • Put shared concerns in the shell and isolate failures per piece.

Further reading