AWS Builder Center
A Microfrontend Platform Assessment: Questions to Answer Before You Build

A Microfrontend Platform Assessment: Questions to Answer Before You Build

Frameworks come last. Before you reach for Module Federation, single-spa, or native federation, answer the questions that actually shape the architecture. This is the checklist I run against a design — treat any item you can't answer cleanly as a gap to close before things lock.

Series: Microfrontends on AWS (2 articles)

  1. 2
    A Microfrontend Platform Assessment: Questions to Answer Before You Build This article
Senior Migration and Modernization Specialist SA
Frameworks come last. Before you reach for Module Federation, single-spa, or native federation, answer the questions that actually shape the architecture. This is the checklist I run against a design — treat any item you can't answer cleanly as a gap to close before things lock.
It's the companion to  Building a Microfrontend Platform on AWS , which makes the case for four load-bearing patterns — composition in one governed place, brokered state, centralized auth, and a governed manifest — by looking at how IKEA, Spotify, DAZN, and American Express run microfrontends in production. This post turns those patterns into questions and maps each to the AWS service that implements it.

Start with why

Are you optimizing for team autonomy and delivery speed, or reaching for reusability? Reusability is a component goal; chasing it across teams recreates the coupling you were trying to escape. If a modular monolith would serve a small team better, build that instead.

Map the teams

Microfrontends are a sociotechnical choice before they're a technical one — the architecture only pays off if it matches how your people actually work (Conway's Law, whether you invoke it or not). So before drawing any boundaries, understand the teams. How are the frontend teams organized — by product, by feature, by layer? How do they ship today: one shared pipeline, or independent releases? Are external agencies or contractors involved, and if so, what do they own and how isolated does it need to be? And most revealing of all: where does it hurt right now — merge queues, release trains, cross-team approvals, a shared component library everyone fights over? The frictions people feel today are the strongest signal for where the seams belong. If the pain isn't about teams blocking each other, microfrontends may be solving a problem you don't have.
 Team Topologies  gives this a useful vocabulary: think of each microfrontend as owned by a stream-aligned team — one that ships a slice of the product end to end — and the shell, design system, and shared libraries as owned by a platform team whose job is to make those stream-aligned teams faster. If your org doesn't map onto something like that today, the microfrontend split will fight your structure rather than fit it — which is a reason to reshape the teams, or to wait.

Identify

Only once you know the teams, split vertically — one view or route per microfrontend — and stay coarse-grained. A view assembled from twenty runtime remotes is a distributed monolith wearing a costume. Draw boundaries from business domains, real traffic, and the team structure you just mapped, and accept that they'll move as the product evolves.

Compose

Where do the pieces get stitched together — on the server or edge before the page arrives, or in the browser at runtime? This is the single choice that ripples furthest: it decides your SEO and first-paint story, how much work the shell does, and where the trust boundary naturally sits. Reach for server- or edge-side composition when SEO or time-to-first-paint matters, and for client-side composition when you're behind a login and want maximum team independence. There's no universal right answer — but there is a right answer for your product, and you should be able to say which and why before you build.
Whichever you pick, keep the shell thin, domain-agnostic, and stable — a good one barely changes after its first year, because all it does is configure, route, and compose.

Share dependencies

Does every remote bundle its own copy of React (or Angular, or whatever it uses), or do they share one runtime? This is the axis IKEA settled bluntly — no shared frameworks in the browser — while Zalando codified the opposite into an explicit shared-dependency contract, and it's exactly what Module Federation's version negotiation exists to manage. Sharing shrinks bundle size but couples every remote to one version; isolating keeps teams independent but ships the framework many times over. Decide where you sit, and how you'll handle version skew when one team needs to upgrade and another isn't ready — because "we'll all upgrade together" is the coupling you were trying to escape.
A related question: one framework, or many? Module Federation lets React, Angular, and Next.js coexist in one page, which sounds liberating and occasionally is — but every extra framework is another runtime to download and another version matrix to reason about. Allow heterogeneity only where a team genuinely needs it (a migration, an acquisition), not by default.

Stay consistent

If independent teams ship independently, what stops the product from looking like five different products? The answer is a design system owned as a product — shared components, tokens, and styles that every remote consumes, maintained by the platform team so the stream-aligned teams stay visually coherent without coordinating every release. Version it, document it, and treat breaking changes to it as the serious events they are. Without this, "independent deployment" quietly becomes "inconsistent UX," and users feel the seams you worked so hard to hide.

Route

Let the shell own navigation between remotes, and let each remote own its internal routing. For migrations, route at the edge so legacy-versus-new is a config flag, not a code change — which also buys you instant rollback.

Communicate

Favor an event emitter over a shared global store — the latter is a documented multi-month refactor trap. Keep each remote's state local, and for anything sensitive, broker it through a scoped interface rather than exposing it globally.

Isolate

At runtime, every remote shares one origin and one page — so a remote that crashes, leaks memory, or misbehaves can drag down the whole product unless you contain it. How much blast-radius protection do you need? Intuit gives each plugin a sandbox as its only route to shared capabilities; DAZN hands each remote a controlled interface rather than raw globals. Decide your equivalent: wrap each remote in an error boundary so one bad deploy degrades a panel, not the page, and mediate access to shared capabilities (storage, messaging, auth) through a narrow interface the platform controls rather than letting remotes reach for whatever they like.

Secure

This is where the assessment earns its keep, because the failure modes are remarkably consistent from team to team:
  • Verify before execute. Emit a signed manifest with a per-chunk integrity hash, and have the shell check both before running any remote. Highest-impact control on this list — it neutralizes a compromised or swapped remote.
  • Enforce authorization at the API, never the shell alone. Every remote is reachable at its own URL and bypasses the shell's gate, so client-side gating decides what to render, not what a user may access.
  • Keep tokens out of browser storage. Web Storage is shared across every remote in one origin, so a single XSS bug reads everything. Hold the token in a shell-owned closure or service worker that injects it for allow-listed domains and never hands it back to the page.
  • Set the identity cookie to lax same-site, not strict — or single-sign-on redirect returns and deep links break. Add CSRF protection on any endpoint the cookie alone authenticates.
  • Take the content-security-policy off any wildcard and add Trusted Types — a browser feature that blocks scripts from unapproved sources — so one subdomain takeover can't serve trusted script into production.

Operate

If every API call depends on the auth and session store, treat it as tier-0 — never allowed to fail — and cache the revocation check so an availability wobble doesn't take the platform down with it. Wrap each remote in an error boundary, so one team's bad deploy degrades a panel, not the product. And keep a short edge-TTL floor with a last-good manifest, so a near-zero-TTL entry file never becomes a single point of failure.

The AWS service map

Each decision above has a service that makes it cheaper to build than rolling your own.
Assessment step
What you're building
AWS service
Notes
Route
Edge routing of legacy-vs-new and between remotes
CloudFront + Lambda@Edge / CloudFront Functions
Path-based routing as a config flag; instant rollback
Compose
Runtime composition + static delivery
CloudFront + Amazon S3
Immutable content-hashed chunks behind a low-TTL entry manifest
Secure — verify before execute
Signed manifest with per-chunk integrity hash
S3 +
 awslabs/frontend-discovery 
Signed deployment schema the shell verifies before running any remote
Secure — centralized auth
Identity, federation, entitlement claims
Amazon Cognito +
 pre-token generation Lambda 
Stamps scoped entitlements into the signed token server-side
Secure — enforce at the API
Authorization at the edge/API, not the shell
API Gateway / Lambda authorizers
Client-side gating decides what to render, not what a user may access
Operate — resilience
Error isolation, cache discipline
CloudFront cache behaviors + last-good manifest floor
Short edge-TTL floor so a near-zero-TTL entry file isn't a single point of failure
One rule of thumb worth internalizing, from the  AWS edge-functions guidance : reach for CloudFront Functions on header and URL work, and Lambda@Edge when you need a network call or heavier logic.

Where to start

If there's one thing to take away, it's this: pick one vertical slice and take it end to end — build, signed manifest, edge verification, API enforcement — before you scale to twenty remotes. That first slice surfaces every hard problem at a size you can still reason about, and it becomes the template for everything after. Get verify-before-execute in place first, since it neutralizes the highest-impact risk, then layer write governance, a scoped content-security-policy, and cache discipline on top.
For the why behind these questions — the production write-ups and the four patterns they converge on — see the companion,  Building a Microfrontend Platform on AWS .

Further reading




About the author

Sylvain Leroy is a Migration and Modernization Solutions Architect at AWS with 20 years of experience across frontend, backend, and cloud architecture. He works with enterprise teams on distributed systems, application modernization, and secure platform design.

Series: Microfrontends on AWS (2 articles)

  1. 2
    A Microfrontend Platform Assessment: Questions to Answer Before You Build This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article