Module Federation in React

Building Scalable React Applications with Module Federation
Modern web applications are growing at an unprecedented scale. Codebases are expanding, teams are scaling, and release cycles are accelerating. In this fast-paced development world, Module Federation stands out as a game-changer for building scalable and independent frontend applications.
π§ What is Module Federation?
Module Federation is a feature introduced in Webpack 5 (see Webpack) that allows multiple independently-built and deployed applications (or βmodulesβ) to share code and functionality with each other at runtime.
It is an innovative feature that enables dynamic sharing of code and functionality between independently built applications at runtime. By eliminating the need for tightly coupled builds, it fosters seamless collaboration and reuse across projects.
This capability makes Module Federation a key enabler of the micro-frontend architecture, where large frontend applications are divided into smaller, independently deployable units. This approach enhances scalability, accelerates development, and empowers teams to work autonomously. For a deeper dive, check out Martin Fowler's article on Micro-Frontends.
In simpler terms:
- It lets App A use components or utilities from App B without importing it during build time.
- All sharing happens at runtime.
π§© Micro Frontends: An architectural approach where frontend applications are broken down into smaller, independently deployable apps that work together.
π Webpack: A module bundler that packages JavaScript code for usage in a browser.
π Why Should You Care About Module Federation?
Imagine you're building a product with multiple teams:
- One team handles authentication
- Another handles dashboard
- A third team builds analytics
Without Module Federation, you'd likely:
- Merge all code into a monolith
- Rebuild everything on every change
- Coordinate deployments like a game of Tetris
With Module Federation:
- β Teams build and deploy independently
- β Apps share components and libraries at runtime
- β Performance improves through lazy loading
- β You avoid code duplication (like React loaded multiple times)
Itβs like giving every team their own spaceship β yet letting them dock with the mothership when needed π
π When Should You Use Module Federation?
Use Module Federation when:
- You're building micro frontends
- Your application is growing too large for one team to manage
- You want independent deployments
- You need to reuse components across projects
- You want to experiment without breaking the monolith
Avoid it if:
- Your app is simple and tightly coupled
- You donβt want the overhead of managing multiple repos and deployments
π§ How Does Module Federation Work?
Letβs explore using the GitHub repository: ajaysskumar/module-federation-demo
π Project Structure
module-federation-demo/
βββ host-app/ # The main app consuming components
βββ remote-app/ # The app exposing components
Running remote app
π Step 1: Setup the Remote App
The remote-app
exposes a FruitsTable
component.
The below code snippet configures the Webpack Module Federation Plugin for the remote-app
. It specifies:
- name: The unique name of the remote application (
remoteApp
). - filename: The name of the file (
remoteEntry.js
) that will act as the entry point for exposing modules. - exposes: Declares the modules/components to be exposed by the remote app. Here, the
FruitsTable
component is exposed. - shared: Specifies shared dependencies like
react
andreact-dom
, ensuring they are loaded as singletons to avoid duplication.
π remote-app/webpack.config.js
new ModuleFederationPlugin({
name: "remoteApp",
filename: "remoteEntry.js",
exposes: {
"./FruitsTable": "./src/FruitsTable",
},
shared: {
react: {
singleton: true
},
"react-dom": {
singleton: true
},
},
})
Code Sample #1 : Running remote app
π remote-app/src/FruitsTable.js
const FruitsTable = () => (
<div>
<h1 style={{ textAlign: "center", color: "green" }}>Hello from Remote App component</h1>
<table style={{ width: "50%", margin: "0 auto", borderCollapse: "collapse" }}>
<thead>
<tr>
<th style={{ border: "1px solid black", padding: "8px", backgroundColor: "#f2f2f2" }}>Name</th>
<th style={{ border: "1px solid black", padding: "8px", backgroundColor: "#f2f2f2" }}>Quantity</th>
<th style={{ border: "1px solid black", padding: "8px", backgroundColor: "#f2f2f2" }}>Price</th>
</tr>
</thead>
<tbody>
{fruits.map((fruit, index) => (
<tr key={index}>
<td style={{ border: "1px solid black", padding: "8px", textAlign: "center" }}>{fruit.name}</td>
<td style={{ border: "1px solid black", padding: "8px", textAlign: "center" }}>{fruit.quantity}</td>
<td style={{ border: "1px solid black", padding: "8px", textAlign: "center" }}>${fruit.price.toFixed(2)}</td>
</tr>
))}
</tbody>
</table>
</div>
);
Code Sample #2 : FruitsTable remote component
Run remote-app:
cd remote-app
npm install
npm start
# Runs at http://localhost:3001
Code Sample #3 : Running remote app
π§² Step 2: Consume in the Host App
The above code snippet configures the Webpack Module Federation Plugin for the host application. It specifies:
- name: The unique name of the host application (
hostApp
). - remotes: Declares the remote application (
remoteApp
) and its entry point (http://localhost:3001/remoteEntry.js
). - shared: Ensures that dependencies like
react
andreact-dom
are loaded as singletons to avoid duplication across the host and remote apps.
π host-app/webpack.config.js
new ModuleFederationPlugin({
name: "hostApp",
remotes: {
remoteApp: "remoteApp@http://localhost:3001/remoteEntry.js",
},
shared: {
react: {
singleton: true,
},
"react-dom": {
singleton: true
},
},
})
Code Sample #4 : Module Federation Plugin setup in webpack config

host-app/src/App.js
import React, { Suspense, lazy } from "react";
const RemoteFruitsTable = lazy(() => import("remoteApp/FruitsTable"));
function App() {
return (
<Suspense fallback=<div>This is host app. Remote will be loaded soon..</div>>
<RemoteFruitsTable />
</Suspense>
);
}
export default App;
Code Sample #5 : Host app consuming remote component
Run host-app:
cd host-app
npm install
npm start
# Runs at http://localhost:3000
Code Sample #6 : Running host app
Boom! π The host renders a Fruits table from the remote app β without bundling it.

Notice the network tab in above image to see remoteEntry.js
file being loaded from http://localhost:3001
π‘ And the best part? You can update the remote app independently, and the host will always fetch the latest version at runtime.
π§ Key Concepts at a Glance
Term | Description |
---|---|
Host | App consuming remote modules |
Remote | App exposing modules |
Exposes | Declares what components the remote provides |
Remotes | Declares what the host will consume |
Singleton | Ensures only one instance of a library (like React) is used |
Lazy Loading | Load components on demand |
π₯ Final Thoughts β Why You Should Try Module Federation
Module Federation isnβt just a tool β itβs a new way of thinking:
- It breaks silos between frontend teams
- It speeds up development by reducing inter-team dependencies
- It helps you build faster, ship sooner, and scale better
If you're working on a React app with growing complexity, you owe it to your team to explore Module Federation.
By adopting it, you're not only making your architecture more resilient β you're also unlocking a whole new level of collaboration and efficiency π
π Demo Repository
Check out the complete working code:
π ajaysskumar/module-federation-demo
Want help setting this up for your team or project? Letβs chat. Module Federation can be your next superpower. πͺ