Scaling a Payment Platform with Webpack Module Federation
How independent, dependency-free microfrontends let multiple teams ship a payment system in parallel — the wins, the traps, and the patterns that actually held up in production.
When a payment platform grows past a handful of teams, the monolithic frontend becomes the bottleneck. Every release is a coordination problem. Module Federation was how we broke that deadlock — but it came with sharp edges worth knowing before you adopt it.
Why Module Federation
The core idea: each microfrontend is built and deployed independently, then composed at runtime. A "host" app loads "remotes" over the network, so the checkout team can ship without waiting for the wallet team.
// webpack.config.js (remote: wallet)
new ModuleFederationPlugin({
name: "wallet",
filename: "remoteEntry.js",
exposes: {
"./WalletWidget": "./src/WalletWidget",
},
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
});
The shared config is the part people underestimate. Get singleton: true wrong and you ship two copies of React — hooks break in ways that are miserable to debug.
The three traps
- Version drift in shared deps. Pin shared singletons and fail loudly when versions mismatch, rather than silently loading a second copy.
- Runtime failures cascade. A remote that 404s shouldn't take down the host. Wrap every remote in an error boundary with a graceful fallback.
- Design-system duplication. Share the design system as a singleton remote too, or every team's bundle balloons.
What actually paid off
The measurable win wasn't performance — it was independent deploy cadence. Teams went from a shared weekly train to shipping several times a day. That's the number that matters to a business.
If you're evaluating microfrontends, don't do it for the tech. Do it when team coordination is your real bottleneck.