Summary
Microfrontends split a single frontend into separately owned, separately deployed slices. Webpack and Rspack Module Federation wire them together at runtime: one host app loads remote chunks on demand, sharing singletons like React across the boundary. The tradeoff is team autonomy against a new class of runtime dependency failures.
Jump to the interview angleMicrofrontend
A microfrontend is a vertical slice of UI owned by one team — its own repo, build, and deploy pipeline. The browser assembles the page from multiple independently deployed artifacts.
Module Federation (Webpack 5 / Rspack) is the dominant runtime integration mechanism. A remote exposes modules via exposes in its ModuleFederationPlugin config; a host declares those remotes in remotes and imports them as local. The host fetches the remote's manifest at runtime, then loads only the needed chunks.
Build-time vs runtime: npm packages are build-time — simpler but every consumer rebuilds on change. Module Federation is runtime — a remote's latest build is live to all hosts on deploy.
Module Federation config — host and remote
The remote exposes a component at a stable key; the host maps that key to a CDN URL. Both declare React as a singleton so one copy runs in the page.
// remote/webpack.config.js — the "catalog" microfrontend
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = {
output: { publicPath: "auto" },
plugins: [
new ModuleFederationPlugin({
name: "catalog",
filename: "remoteEntry.js",
exposes: {
"./ProductCard": "./src/components/ProductCard",
},
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true, requiredVersion: "^18.0.0" },
},
}),
],
};
// host/webpack.config.js — the shell app
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: "shell",
remotes: {
catalog: "catalog@https://cdn.example.com/catalog/remoteEntry.js",
},
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true, requiredVersion: "^18.0.0" },
},
}),
],
};The host imports catalog/ProductCard via React.lazy; Webpack fetches remoteEntry.js at runtime, then the component chunk only when it first renders.
Tradeoffs
Pros
- Teams deploy independently — no cross-team coordination per release.
- Runtime integration: consumers see remote changes without rebuilding.
- Shared singletons prevent duplicate React or router instances when configured correctly.
- A crashing remote can be isolated behind an error boundary.
Cons
- Version-skew in shared deps causes subtle runtime bugs.
- Cold-load waterfall: host fetches remoteEntry.js, then chunks — adds latency.
- Every remote is a separate CDN deployment to monitor and version.
- Local dev needs all remotes running or mocked; DX degrades fast.
Version-skew in shared singletons
If host requires React 18.3 and a remote ships 18.2, federation picks the higher compatible version. If versions are truly incompatible, the remote loads its own copy — doubling React in the page and breaking hooks context. Both sides must declare the same dep in shared with matching requiredVersion ranges, or federation cannot negotiate a single instance.
Interview angle
Focus on the runtime mechanism and failure modes, not config syntax. Explain host/remote, shared singletons, and version-skew. Contrast build-time (npm packages) vs runtime integration. Name Next.js Multi-Zones as a simpler alternative for full framework isolation.
Soundbite: "Module Federation lets teams deploy independently; the risk is version-skew in shared singletons and a cold-load waterfall."
Key terms
- Host
- The app that consumes remote modules at runtime; declares `remotes` in its federation config.
- Remote
- A separately deployed build that exposes modules via `exposes` and a `remoteEntry.js` manifest.
- exposes
- Federation config key mapping a public name to an internal module path the remote makes consumable.
- shared singleton
- A dep declared `singleton: true` so federation loads one copy across all host/remote boundaries.
- Multi-Zones
- Next.js feature routing separate Next.js apps by URL prefix via a reverse proxy; no shared JS runtime.