๐Ÿณ IntuitiveFE
Login
โ† All concepts

Micro-Frontends & Module Federation

โฑ๏ธ ~4-minute bite ยท solve the sandbox to master

0%lesson
๐Ÿง’

5-Year-Old Metaphor

โ€” The physical, real-world picture. No jargon.

๐Ÿ™๏ธ City districts โ€” each team owns their district and deploys independently. Shared infrastructure (design system, auth, router) is the power grid.

Why micro-frontends exist

When a frontend codebase grows large enough, it hits scaling problems โ€” not technical, but organizational. A single repository with 50 engineers means merge conflicts, slow CI, coordination overhead on every release, and tight coupling between unrelated features. Micro-frontends are the frontend answer to microservices: let teams own their slice end-to-end and deploy independently.

Monolith frontend

  • โ€ข All teams commit to one repo
  • โ€ข One CI/CD pipeline
  • โ€ข Coordinated releases
  • โ€ข Shared tech stack
  • โ€ข Simple deployment

Micro-frontends

  • โ€ข Teams own separate repos
  • โ€ข Independent CI/CD per team
  • โ€ข Deploy any time
  • โ€ข Tech stack per team (risky)
  • โ€ข Complex composition

Shared infrastructure โ€” the power grid

Even with independent MFEs, teams share some infrastructure โ€” the design system, authentication service, analytics, and the shell app (router). This is analogous to city infrastructure: each district controls its own buildings, but shares roads, water, and power.

Design systemShared UI components โ€” buttons, forms, modals
Auth serviceOne login, one session โ€” all MFEs check the same token
Shell / routerMounts/unmounts MFEs based on URL
AnalyticsOne tracking ID, event schema shared across all teams
Error monitoringUnified error dashboard across all MFEs

Communication patterns

Custom Events: MFE dispatches window.dispatchEvent(new CustomEvent('cart:added', { detail: item })). Shell or other MFEs listen. Decoupled but hard to type-check.

Shared state service: A tiny shared library (not React state) that each MFE can import. An event bus or observable. The "city radio" that all teams can broadcast on.

URL / query params: The most decoupled. MFE A navigates to a URL with params; MFE B reads those params. Works across page loads.

๐ŸŽ›๏ธ

Interactive Sandbox

โ€” Move something, see it react instantly.

Integration pattern

E-commerce app โ€” team ownership

Shell App (platform team) โ€” routes, auth, design system

Header MFE

Platform team

โ† remote module

Product MFE

Catalog team

โ† remote module

Cart MFE

Commerce team

โ† remote module

Checkout MFE

Payments team

โ† remote module

JS / CSS isolation level

Shared

Explicit shared config in webpack.config.js โ€” singleton:true for React to ensure one instance

Webpack 5 Module Federation โ€” micro-frontends expose JavaScript modules that other apps can consume at runtime. Each app can share dependencies (React, etc.) to avoid duplication.

Pros

+Runtime code sharing โ€” load remote components on demand

+Shared deps config โ€” one React instance across all MFEs

+Independent deployments โ€” remotes can update without host rebuild

+Bi-directional โ€” host can also expose modules to remotes

Cons

โˆ’Webpack-specific (Vite Federation plugin exists but less mature)

โˆ’Version negotiation can be tricky (singleton: true required for React)

โˆ’Type sharing requires extra tooling (@module-federation/typescript)

โˆ’Build configuration complexity

Example: IKEA, Zalando, many enterprise apps
Gotcha: React must be configured as a singleton in Module Federation. If host and remote both include React without singleton:true, you get two React instances โ€” hooks will fail with 'invalid hook call' errors.
Insight: Module Federation differs from npm packages in one key way: npm packages are bundled at build time (you ship the code). Module Federation resolves and loads remotes at runtime โ€” the remote URL can change without rebuilding the host.
Explored:๐Ÿ–ผ๏ธ๐Ÿงฉโš™๏ธ๐Ÿ”Œ๐Ÿ“ฆ
๐ŸŽฏ

Challenge

Explore all 5 micro-frontend patterns. For each, ask: can teams deploy independently? What happens when two MFEs need different React versions? What breaks across the boundary?

Try it
๐ŸŽฏ

Why Should I Care?

โ€” The exact interview question + the bug it kills.

Interview questions

Q: When does micro-frontend complexity pay off?

When: multiple teams (5+) work on the same UI, teams need to release on different schedules, teams have different tech stacks (legacy + new), or the monolith has become a deployment bottleneck. Not when: small team, single release cadence, or technical complexity would exceed the organizational benefit. A monorepo with good code ownership tooling (CODEOWNERS, Nx affected) often solves the same problems with less complexity.

Q: Module Federation vs npm packages โ€” key difference?

npm packages are resolved at build time โ€” when you install a package, its code is bundled into your output. If the package updates, you must reinstall and rebuild. Module Federation resolves at runtime โ€” the remote URL is fetched when the user loads your app. The remote can update (deploy a new version) without the host needing to rebuild. This is what enables true independent deployment.

Bug: Duplicate React instances breaking context

js
1// โœ— Host and remote both bundle React separately
2// Host: react@18.2.0 (bundled)
3// Remote: react@18.2.0 (bundled separately)
4// Two React instances โ†’ useContext returns undefined across boundary
5ย 
6// โœ“ Module Federation: share React as singleton
7// webpack.config.js (host AND remote must both do this)
8shared: {
9 react: { singleton: true, requiredVersion: '^18.0.0' },
10 'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
11},
12// Now one React instance shared โ€” context works across MFEs
๐Ÿ”ฌ

The Deep Dive

โ€” Spec refs, engine internals, the minutiae.

Webpack 5 Module Federation config

js
1// Remote (Product MFE) โ€” exposes its components
2new ModuleFederationPlugin({
3 name: 'productApp',
4 filename: 'remoteEntry.js',
5 exposes: {
6 './ProductCard': './src/components/ProductCard',
7 './ProductList': './src/components/ProductList',
8 },
9 shared: {
10 react: { singleton: true, requiredVersion: '^18.0.0' },
11 },
12});
13ย 
14// Host (Shell) โ€” loads the remote
15new ModuleFederationPlugin({
16 name: 'shell',
17 remotes: {
18 productApp: 'productApp@https://product.example.com/remoteEntry.js',
19 },
20 shared: { react: { singleton: true } },
21});
22ย 
23// Usage in host
24const ProductCard = React.lazy(() => import('productApp/ProductCard'));

Testing micro-frontends in isolation

Each MFE should run standalone in development (with mocked shell APIs). Use a contract-testing approach: the shell publishes a contract (auth service API, custom event schema), and each MFE validates against it in CI. This prevents "works in isolation, breaks in the shell" problems.

js
1// MFE dev server: mock the shell's API surface
2// src/mocks/shell.ts
3window.__shell = {
4 auth: { user: { id: '123', name: 'Test User' } },
5 navigate: (url) => console.log('Navigate to:', url),
6 analytics: { track: (event) => console.log('Track:', event) },
7};
8// MFE reads window.__shell in production โ€” shell injects real values
๐ŸŽค

Interview Questions

โ€” Real questions from real interviews โ€” with answers.

They solve organisational scaling โ€” independent team deploys. They add complexity that isn't justified for small teams or single-release-cadence products.

npm packages are resolved at build time; Module Federation resolves remote modules at runtime โ€” the remote can deploy a new version without the host rebuilding.

Two React instances in one page cause 'Invalid hook call' errors because hooks rely on React's internal state that is instance-specific.

Custom events on window, a shared non-React event bus, or URL/query params โ€” all avoid direct imports across MFE boundaries.

Unit/component tests per MFE with mocked shell APIs; contract tests to validate the shell's API surface; E2E tests in the composed shell.

๐ŸŽฎ

Memory Game

โ€” Quick quiz โ€” lock the concept in long-term memory.
1/4

What is the key difference between iframe isolation and Module Federation isolation?