Modern enterprise applications are growing in size and complexity. As teams scale and features evolve independently, a single monolithic frontend becomes difficult to maintain and deploy.
Micro Frontends (MFEs) offer a scalable solution by breaking large applications into smaller, independently deployable units each owned by separate teams.
With Webpack 5 Module Federation, Angular now provides a native and efficient way to implement Micro Frontends without complex runtime integrations.
This article explains how Module Federation works in Angular, its benefits, and a step-by-step implementation guide for integrating multiple micro frontends within a single shell application.
1. Understanding Micro Frontends
A Micro Frontend Architecture divides a large web application into multiple independent applications — or micro apps — that can:
Be developed and deployed separately
Use different versions of Angular or other frameworks
Communicate seamlessly within a unified user experience
Each micro frontend (MFE) handles a specific domain, such as:
These are then composed dynamically by a Shell (Host) application.
2. What is Module Federation?
Module Federation (introduced in Webpack 5) allows multiple applications to share code and load remote modules dynamically at runtime.
Key Concepts
Host – The main application that loads other micro frontends.
Remote – A standalone micro frontend that exposes certain modules/components.
Shared Libraries – Dependencies (like Angular, RxJS, or common UI libraries) that can be shared between host and remotes to prevent duplication.
3. Setting Up the Environment
Prerequisites
Step 1: Install the Module Federation Plugin
npm install @angular-architects/module-federation --save-dev
4. Creating the Applications
Step 2: Generate the Shell and Micro Frontends
ng new mfe-shell --routing --style=scss
ng new mfe-orders --routing --style=scss
ng new mfe-inventory --routing --style=scss
Each app runs independently at first.
5. Configuring Module Federation
Step 3: Configure the Host (Shell)
Navigate to the shell app and run:
ng add @angular-architects/module-federation --project mfe-shell --type host
This creates a webpack.config.js with placeholders to load remote apps.
Example configuration:
// mfe-shell/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
const mf = require('@angular-architects/module-federation/webpack');
module.exports = {
output: {
uniqueName: "mfeShell",
publicPath: "auto",
},
plugins: [
new ModuleFederationPlugin({
remotes: {
"mfeOrders": "mfeOrders@http://localhost:4201/remoteEntry.js",
"mfeInventory": "mfeInventory@http://localhost:4202/remoteEntry.js",
},
shared: mf.share({
"@angular/core": { singleton: true, strictVersion: true },
"@angular/common": { singleton: true, strictVersion: true },
"@angular/router": { singleton: true, strictVersion: true },
}),
}),
],
};
Step 4: Configure a Remote Application
For the mfe-orders app:
ng add @angular-architects/module-federation --project mfe-orders --type remote --port 4201
Generated webpack.config.js example:
new ModuleFederationPlugin({
name: "mfeOrders",
filename: "remoteEntry.js",
exposes: {
"./OrdersModule": "./src/app/orders/orders.module.ts",
},
shared: mf.share({
"@angular/core": { singleton: true, strictVersion: true },
"@angular/common": { singleton: true, strictVersion: true },
"@angular/router": { singleton: true, strictVersion: true },
}),
}),
Do the same for mfe-inventory (on port 4202).
6. Consuming Remote Modules in the Shell
In the shell’s routing configuration:
const routes: Routes = [
{
path: 'orders',
loadChildren: () =>
loadRemoteModule({
type: 'module',
remoteEntry: 'http://localhost:4201/remoteEntry.js',
exposedModule: './OrdersModule',
}).then(m => m.OrdersModule),
},
{
path: 'inventory',
loadChildren: () =>
loadRemoteModule({
type: 'module',
remoteEntry: 'http://localhost:4202/remoteEntry.js',
exposedModule: './InventoryModule',
}).then(m => m.InventoryModule),
},
];
Now, navigating to /orders or /inventory in the shell dynamically loads the respective remote application.
7. Sharing Common Libraries
To reduce bundle size and maintain consistency:
Share Angular core libraries (@angular/core, @angular/common)
Share UI component libraries (like PrimeNG or Material)
Share custom libraries (like a design system or common services)
You can modify webpack.config.js in each project:
shared: mf.share({
"@angular/core": { singleton: true, strictVersion: true },
"@angular/common": { singleton: true, strictVersion: true },
"@angular/router": { singleton: true, strictVersion: true },
"shared-lib": { singleton: true, import: "shared-lib" },
}),
8. Running and Testing
Start all apps in separate terminals:
ng serve mfe-orders --port 4201
ng serve mfe-inventory --port 4202
ng serve mfe-shell --port 4200
Open
http://localhost:4200/orders
http://localhost:4200/inventory
You’ll notice the shell dynamically loads content from the micro frontends.
9. Deployment and Versioning
Each MFE can:
Have its own repository
Be deployed independently (e.g., on Azure Blob, AWS S3, or CDN)
Expose its remoteEntry.js file via public URL
The shell always loads the latest version at runtime — no redeployment required for the entire app.
10. Advantages of Using Module Federation in Angular
True decoupling: Teams can work independently without merge conflicts.
Independent deployments: Each feature or domain can be deployed separately.
Version flexibility: Micro frontends can use different Angular versions.
Performance optimization: Shared dependencies reduce duplication.
Scalable architecture: Perfect for enterprise-level applications.
11. Real-World Use Cases
ERP systems with independent modules like Finance, Inventory, and Sales.
Multi-tenant platforms where different clients require customized frontends.
Product suites where each product has its own lifecycle but unified branding.
12. Conclusion
Integrating Micro Frontends using Module Federation in Angular provides a robust foundation for building scalable, modular, and future-proof enterprise applications.
By combining independent deployability with shared runtime integration, Module Federation eliminates the pain of monolithic frontends and empowers teams to innovate faster without sacrificing consistency or maintainability.