Micro Frontend Guide
Approaches Comparison
| Approach | Integration | Isolation | Complexity | Best For |
|---|---|---|---|---|
| Module Federation (Webpack 5) | Build-time | Shared runtime | Medium | React/Vue apps, tight integration |
| single-spa | Runtime | Per-app isolation | High | Mixed frameworks, legacy migration |
| Web Components | Runtime | Shadow DOM isolation | Low-Medium | Framework-agnostic widgets |
| iframes | Runtime | Complete | Low | Third-party integrations |
| Server-Side Composition | Server | Complete | Medium | SSR pages, Edge Side Includes |
Module Federation (Webpack 5)
// Host app — webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
// remote-app exposed at this URL
checkout: 'checkout@https://checkout.example.com/remoteEntry.js',
catalog: 'catalog@https://catalog.example.com/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
}),
],
};
// Remote app — webpack.config.js
new ModuleFederationPlugin({
name: 'checkout',
filename: 'remoteEntry.js',
exposes: {
'./CheckoutFlow': './src/CheckoutFlow',
'./CartButton': './src/CartButton',
},
shared: { react: { singleton: true } },
})
// Usage in host
const CheckoutFlow = React.lazy(() => import('checkout/CheckoutFlow'));
Communication Patterns
| Pattern | Use Case | Example |
|---|---|---|
| Custom Events | Loose coupling, same-page events | window.dispatchEvent(new CustomEvent('cart:add', {detail: item})) |
| Shared State (Redux) | Global state across MFEs | Single store in host, consumed by remotes |
| URL / Route params | Navigation data | React Router or native history API |
| Props / Callbacks | Parent-child MFE data | Module Federation exposed component props |
| BroadcastChannel | Cross-tab communication | new BroadcastChannel('app') |