Micro-FrontendsMS-04 · theory

Source · Geers, Building Micro-Frontends (O'Reilly)

Why this matters

Geers, Building Micro-Frontends, Ch. 1 (My First Micro-Frontends Project)

Microservices give backend teams autonomy, but if every team's work still funnels into a single monolithic frontend, the frontend becomes a shared bottleneck: teams queue to merge into one codebase, one release train, one deployment. Micro-frontends extend the microservices philosophy to the browser, letting a team own a vertical slice of a product from database to UI and ship it independently.

Understanding this matters because the frontend is where microservices architectures most often re-monolithize. Solving decomposition in the backend while leaving a monolithic UI leaves you with only half the autonomy you were chasing.

The concept

Geers, Building Micro-Frontends, Ch. 4-8 (Composition techniques)

A micro-frontend is an independently deployable piece of a user interface, owned by a team that ideally also owns the backend for that capability - a full vertical slice. The central design question is composition: how independently built UI fragments are assembled into one page. There are three broad places this can happen.

Build-time composition combines fragments as packages/libraries during the build. It is simple but re-couples release: publishing a new fragment version means the container app must rebuild and redeploy, which undermines independent deployment.

Server-side composition assembles fragments on the server before sending HTML to the browser (for example via edge-side or server-side includes). It gives good performance and lets fragments deploy independently.

Run-time (client-side) composition stitches fragments together in the browser, often via a container app, iframes, web components, or module federation. It maximizes independent deployment - each team ships its fragment and the container picks it up at run time - at the cost of more client-side coordination.

The recurring theme is team autonomy: micro-frontends exist to let teams deploy independently, and the composition choice is largely about preserving that autonomy while managing consistency, performance, and shared concerns like design systems.

Worked scenario

Geers, Building Micro-Frontends, Ch. 6-7 (Client-side composition, shared concerns)

An e-commerce site has separate teams for Catalog, Product Detail, and Checkout. Initially all three edit one React monolith; every deploy is a coordinated release, and a Checkout hotfix waits behind unrelated Catalog work.

They adopt run-time composition. Each team builds and deploys its own fragment independently; a thin container application composes them per route - Catalog owns the listing page, Product Detail owns the item page, Checkout owns the cart and payment flow. Now Checkout can hotfix and deploy in minutes without touching the others. To keep the experience coherent, all teams consume a shared design system so buttons and typography stay consistent, and they agree on a lightweight contract for cross-fragment navigation and shared state (like the cart badge).

The trade-offs surface immediately: bundle sizes can duplicate (each fragment may ship its own framework copy), and visual/UX consistency now depends on shared conventions rather than a single codebase. These are the classic micro-frontend costs, weighed against the autonomy gained.

How it connects

Geers, Building Micro-Frontends, Ch. 12-14 (Global concerns, when to use)

Micro-frontends are the frontend expression of the same principles as backend microservices: independent deployability, team ownership of a bounded slice, and loose coupling via explicit contracts. The composition contract between fragments mirrors the API contracts between services, and the shared design system plays the governance role that API governance plays on the backend.

They pair naturally with the BFF pattern: a team's fragment often talks to that team's own BFF, so the vertical slice runs UI-to-data. And the trade-off analysis is the same discipline as the fundamentals: adopt micro-frontends when the frontend has become a genuine bottleneck to autonomy, not by default - because you take on duplicated bundles, consistency work, and integration complexity in exchange.

Common traps
  • Assuming build-time composition preserves independent deployment. Publishing a new fragment version forces the container to rebuild and redeploy, re-coupling releases.
  • Ignoring shared-concern consistency. Without a shared design system and cross-fragment conventions, independently built UIs drift in look, behavior, and duplicated dependencies.
  • Adopting micro-frontends by default. They add integration complexity and bundle duplication; use them only when a monolithic frontend is a real bottleneck to team autonomy.
Key takeaways
  • Micro-frontends extend microservices' independent deployability and team ownership to the browser, giving each team a full vertical slice.
  • Composition happens at build-time (simple but re-couples deploys), server-side (good performance, independent deploys), or run-time (max autonomy, more client coordination).
  • The gains are team autonomy and independent deployment; the costs are consistency work, duplicated bundles, and integration complexity - adopt deliberately.