RTS questionnaire · Q29 · Micro-frontend proof

Have you worked with Micro-frontends? If yes, which architecture or framework did you use?

A runnable review of the three micro-frontend strategies I have used, the governance that makes runtime composition survivable, and the check I run before recommending the split at all.

Status: reviewed Live micro-frontend workflow Module Federation · Web Components · single-spa Jump to live proof ↓

29. Micro-frontends: architecture and framework

Answer as submitted

“Yes — I have worked with micro-frontend architectures and know how to choose between the available implementation strategies.”
Technical decision: expand. The question asks which architecture or framework, and the submitted line names none of them. This page is the separate, detailed version: it shows each strategy with its runtime mechanics, the shared-dependency rules that keep one framework on the page, the governance, and the threshold at which I advise against the split.

Expanded answer

Yes, with three complementary strategies. Module Federation (webpack/Vite) is the one I reach for first: a host shell resolves independently deployed remotes at runtime, with the framework, the reactivity library and the design system declared as shared singletons under strict version negotiation, so a remote can never bring a second copy of Angular onto the page and a version skew fails the pipeline rather than the user's session. Web Components / Angular Elements is the incremental-modernisation tool: a component is packaged as a framework-agnostic custom element with attributes in and custom events out and shadow DOM for style isolation, so a legacy page, a React host and an Angular host can all mount it. Route-based orchestration (single-spa style) is the composition model: each vertical is owned by one team, mounted under its own route and downloaded only when that route is active, while the shell keeps exactly what must be common — authentication and token refresh, navigation, theming, error boundaries and analytics. All three only work with governance: a versioned design system, events as the sole cross-team channel, no deep imports across remotes, one CI/CD pipeline per remote and per-remote observability with a named owner. And I say no to micro-frontends when the team count, the deployment independence or the framework heterogeneity do not justify the duplicated runtime and the coordination cost — a modular monolith with a shared component library is usually the better trade.

StrategyHow it composesBest fit
Module Federation (webpack/Vite)host resolves remotes at runtime, shared singletons with strict version negotiationseveral teams on the same framework shipping independently
Web Components / Angular Elementsframework-agnostic custom elements: attributes in, custom events out, shadow DOMincremental modernisation, widget sharing across frameworks
Route-based orchestration (single-spa)one vertical per route, lazily loaded, shell owns the cross-cutting concernsverticals with clearly separate domains and owners
Shared dependenciesdeclared singletons, strict version negotiation at build timekeeping one copy of the framework, RxJS and the design system
Governanceversioned design system, contract-first events, one pipeline per remote, per-remote telemetrymaking independent deployment real rather than nominal
Counter-checkteam count, deployment independence, framework heterogeneitydeciding to stay a modular monolith with a shared component library

Live micro-frontend workflow proof

The running component below changes its strategy/result view through real event binding. Select a strategy, a governance rule or the counter-check to see the mechanics, the reasoning behind the decision, and the evidence that it holds.

LIVE PREVIEW
RUNNING
MICRO-FRONTEND WORKFLOWRUNNING

Choose a strategy or a governance rule

Select a step to inspect the mechanics, the reasoning and the evidence.

$ ModuleFederationPlugin → remotes: { search, analytics, admin } · shared: { @angular/core, rxjs, design-system } (singleton, strictVersion)

A host shell loads independently deployed remotes at runtime. Framework libraries and the design system are shared singletons with strict version negotiation, so Angular, RxJS and the token stylesheet are instantiated once even with three remotes on the page.

remotes loaded at runtime: 3
copies of @angular/core on the page: 1
version mismatch: fails the build, not the user session

What the micro-frontend split buys — and costs

Rules I apply. Make the shared surface explicit and small, because every shared singleton is a reason for two teams to release together; let each vertical expose a versioned contract and forbid deep imports across remotes, so the only cross-team channel is an event or the API; keep authentication, theming and error boundaries in the shell, since four implementations of token refresh is four ways to lock users out; give every remote its own pipeline, owner and telemetry so an incident has one team to page; and degrade a failed remote to a route-level fallback so one team's bad deploy cannot take the whole product down.
Boundary for Q29: this page covers the micro-frontend strategies, their runtime mechanics and the governance around them. Choosing between front-end architecture patterns in general — modular monolith, shared component library, micro-frontend — as a design exercise is Q30.

Source files

Select a file to inspect the proof with syntax highlighting and line numbers. The first file is the code running the component above; the others are the Module Federation configuration, the shell bootstrap and the runtime manifest that records routes, ownership and governance.

Acceptance criteria