Angular  

Integrating Micro Frontends Using Module Federation in Angular

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:

  • orders

  • inventory

  • customers

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

  • Node.js (>= 18)

  • Angular CLI (>= 17)

  • Webpack 5 (comes by default with Angular 12+)

  • @angular-architects/module-federation plugin

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.