Module Federation with Webpack 5
Configure a host and remote app with Webpack Module Federation to share components at runtime.
Module Federation with Webpack 5 is a free React Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Module Federation Overview
Webpack 5 Module Federation lets you share JavaScript modules between separately bundled applications at runtime — one app exposes components, another consumes them without a build step.
Roles: Host vs Remote
A remote exposes modules. A host consumes modules from one or more remotes. An app can be both host and remote simultaneously.
Remote Configuration
In the remote app's webpack.config.js, use ModuleFederationPlugin to expose components.
// Remote: apps/products/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'products', // remote name
filename: 'remoteEntry.js', // entry file
exposes: {
'./ProductCard': './src/components/ProductCard', // exposed module
'./CartButton': './src/components/CartButton',
},
shared: ['react', 'react-dom'], // share deps to avoid duplication
}),
],
};Host Configuration
In the host app's webpack config, declare which remotes to consume and where to load them from.
// Host: apps/shell/webpack.config.js
new ModuleFederationPlugin({
name: 'shell',
remotes: {
products: 'products@http://localhost:3001/remoteEntry.js',
cart: 'cart@http://localhost:3002/remoteEntry.js',
},
shared: ['react', 'react-dom'],
})Consuming a Remote Module
Import remote modules using the remote name as a path prefix. Wrap them in React.lazy and Suspense for lazy loading.
import React, { lazy, Suspense } from 'react';
const ProductCard = lazy(() => import('products/ProductCard'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ProductCard productId="123" />
</Suspense>
);
}Sharing Dependencies
List shared packages with singleton: true so only one copy of React is loaded across all micro-frontends.
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
'@company/design-system': { singleton: true },
},Dynamic Remotes
Load remotes dynamically at runtime from config (e.g., a manifest endpoint) instead of hardcoding URLs in the webpack config.
async function loadRemote(scope, module) {
await __webpack_init_sharing__('default');
const container = window[scope];
await container.init(__webpack_share_scopes__.default);
const factory = await container.get(module);
return factory();
}
const ProductCard = React.lazy(() => loadRemote('products', './ProductCard'));TypeScript with Module Federation
Use the @module-federation/typescript plugin to generate type declarations for exposed modules so hosts get full autocomplete.
Error Boundaries for Remote Failures
Wrap remote components in error boundaries. If a remote fails to load, the host degrades gracefully instead of crashing.
<ErrorBoundary fallback={<div>Product unavailable</div>}>
<Suspense fallback={<Skeleton />}>
<ProductCard productId={id} />
</Suspense>
</ErrorBoundary>Vite Module Federation
The @originjs/vite-plugin-federation plugin brings Module Federation to Vite-based projects with a similar API.
// vite.config.ts (remote)
import federation from '@originjs/vite-plugin-federation';
export default defineConfig({
plugins: [
federation({
name: 'products',
filename: 'remoteEntry.js',
exposes: { './ProductCard': './src/ProductCard' },
shared: ['react'],
}),
],
});Quick Check
What does setting singleton: true for a shared package in Module Federation do?
Recap
Module Federation uses ModuleFederationPlugin in remotes (to expose) and hosts (to consume). Import remote modules with lazy(), share react as a singleton to avoid duplication, and wrap remotes in error boundaries for graceful degradation.
Frequently asked questions
Is the “Module Federation with Webpack 5” lesson free?
Yes — the full text of “Module Federation with Webpack 5” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Module Federation with Webpack 5”?
Configure a host and remote app with Webpack Module Federation to share components at runtime. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Module Federation with Webpack 5” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Micro-Frontend Concepts & Trade-offs
- Module Federation with Webpack 5
- Shared State & Routing Between MFEs
- Independent Deployment & CI Pipelines for MFEs