Micro Frontends Tradeoffs
System design tradeoffs for micro-frontends — composition, ownership, shared deps, perf, and when to avoid them.
- system-design
- interview
- architecture
- micro-frontends
Scope the problem
Micro-frontends (MFEs) split a web app so multiple teams ship independently. Interviews reward honest tradeoffs — MFEs are an org-scaling tool, not a default performance win.
When MFEs make sense
- Multiple teams, different release cadences
- Clear domain boundaries (checkout, catalog, account)
- Platform team can own shell + contracts
- Legacy strangler migration
When they don’t
- Small team / one deployable
- Tight UX coherence requirements without strong design system
- Perf-critical mobile on slow networks (duplicate frameworks risk)
Composition approaches
| Approach | How | Pros | Cons |
|---|---|---|---|
| Build-time packages | monorepo libs | simple types | coupled deploys if not careful |
| iframe | hard isolation | security | UX, routing, a11y pain |
| runtime Module Federation / import maps | load remote entry | independent deploy | version hell |
| Edge/HTML composition | stitch fragments | progressive | complexity |
| Web Components | custom elements | framework-agnostic | data/state plumbing |
Common modern pick: app shell + Module Federation (or native ESM import maps) for remotes.
Reference architecture
┌─────────────────────────────────────────────┐
│ Shell (auth, nav, feature flags, routing) │
├──────────┬──────────┬───────────────────────┤
│ Catalog │ Checkout │ Account (remotes) │
│ MFE │ MFE │ MFE │
├──────────┴──────────┴───────────────────────┤
│ Shared: design system, auth client, telemetry│
└─────────────────────────────────────────────┘
Shell owns:
- top-level router mounts
- session bootstrap
- global cross-cutting concerns
Remotes own:
- domain routes/features
- domain APIs
Shared dependencies
Problem: three Reacts → bloat and broken hooks.
Strategies:
- Shell provides singleton React/ReactDOM as shared
- Strict version alignment in CI
- Design system as shared singleton
- Document allowed shared list
// federation shared sketch
shared: {
react: { singleton: true, requiredVersion: "^18" },
"react-dom": { singleton: true },
}
Routing
- Shell path prefixes:
/checkout/*→ checkout remote - Deep links must load correct remote then inner route
- Avoid multiple History hijacks — single router owner
Communication
| Style | Use |
|---|---|
| URL / query | shareable state |
| Custom events / small event bus | rare cross-MFE notifies |
| Shared query cache carefully | only if singleton client |
| Avoid | deep prop drilling across remotes |
Prefer loose coupling via backend entities, not shared global mutable stores.
Styling isolation
- CSS modules / shadow DOM / strict BEM prefixes
- Shared tokens from design system
- No global CSS resets inside remotes fighting shell
Performance
| Risk | Mitigation |
|---|---|
| Waterfall remote entry | prefetch remotes on intent |
| Duplicate deps | singleton sharing |
| Large shell | keep shell thin |
| Sequential team bundles | parallel load; HTTP/2 |
Measure: bytes per team, TTI of integrated page.
Independent deploy
- Remote builds to versioned URL
- Shell config map:
checkout → https://cdn/.../checkout/3.2.1/remoteEntry.js - Canary per remote
- Rollback by pointer change
Need contract tests between shell and remote public interface.
Observability & ownership
- Tag errors with
mfe: checkout - Ownership CODEOWNERS per remote
- Shared design system versioning policy
Security
- Remotes from trusted origins only
- CSP allows CDN hosts
- Don’t eval arbitrary remote URLs from query strings
Tradeoffs summary
- Team autonomy vs UX consistency
- Runtime composition vs monorepo packages
- Isolation (iframe) vs integration
- Upgrade coordination of shared singletons
Interview close
Start with org problem → choose composition model → shell responsibilities → shared dep singletons → deploy pointer map → perf risks. Explicitly say monorepo modularization often enough without runtime MFEs.
Related on this site
- Design a Design System
- Client-side Routing at Scale
- State Management at Scale
- System Design Interview Framework