Micro-Frontends in Angular: A Guide to Module Federation

What are Micro-Frontends?

Micro-Frontends are a modern architectural approach where a single web application is composed of independent, smaller applications (a.k.a. micro-apps), each managed by different teams and deployed independently. With Micro-Frontends in Angular, this concept becomes especially powerful, leveraging Angular’s strong module system and ecosystem.

Module Federation to the Rescue

Webpack 5’s module federation functionality enables remote module loading at runtime. 

This allows Micro-Frontends in Angular to be integrated seamlessly into a larger host application. Angular CLI 13+ supports Module Federation natively, simplifying the setup process.

Step-by-Step Guide: Micro-Frontend Architecture in Angular

We’ll build:

Shell (Host): The primary application that loads micro frontends.
Remote (Micro App): A feature app like a dashboard or analytics module.

Project Structure

micro-frontends/

├── shell/            # Main host app

└── mfe-dashboard/    # Remote micro-frontend app

Related read: Micro Frontends: Unlocking the Future of Web Development

Step 1: Setup Projects

1. Create Shell App

ng new shell --routing --style=scss
cd shell
ng add @angular-architects/module-federation

Choose:

▪️Host Application
▪️Use default port (4200)

2. Create Remote App (Dashboard)

In the root directory:

ng new mfe-dashboard --routing --style=scss
cd mfe-dashboard
ng add @angular-architects/module-federation

Choose:

▪️Remote Application
▪️Name it dashboard
▪️Port: 4201
▪️Expose Module: ./Module
▪️Path: src/app/dashboard/dashboard.module.ts

Step 2: Configure Module Federation

In mfe-dashboard/webpack.config.js:

const { withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

module.exports = withModuleFederationPlugin({

  name: 'dashboard',

  exposes: {

    './Module': './src/app/dashboard/dashboard.module.ts',

  },

  shared: {

    "@angular/core": { singleton: true, strictVersion: true },

    "@angular/common": { singleton: true, strictVersion: true },

    "@angular/router": { singleton: true, strictVersion: true },

  },

});

Step 3: Expose Dashboard Module

mfe-dashboard/src/app/dashboard/dashboard.module.ts:

import { NgModule } from '@angular/core';

import { CommonModule } from '@angular/common';

import { DashboardComponent } from './dashboard.component';

import { RouterModule } from '@angular/router';

@NgModule({

  declarations: [DashboardComponent],

  imports: [

    CommonModule,

    RouterModule.forChild([{ path: '', component: DashboardComponent }])

  ],

})

export class DashboardModule {}

dashboard.component.ts

import { Component } from '@angular/core';

@Component({

  selector: 'app-dashboard',

  template: `<h2>Micro Frontend Dashboard</h2>`,

})

export class DashboardComponent {}

Step 4: Load Remote Module in Shell

Modify shell/webpack.config.js:

const { withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

module.exports = withModuleFederationPlugin({

  remotes: {

    'dashboard': 'dashboard@http://localhost:4201/remoteEntry.js',

  },

  shared: {

    "@angular/core": { singleton: true, strictVersion: true },

    "@angular/common": { singleton: true, strictVersion: true },

    "@angular/router": { singleton: true, strictVersion: true },

  },

});

Add Route in Shell App

shell/src/app/app-routing.module.ts:

import { NgModule } from '@angular/core';

import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [

  {

    path: 'dashboard',

    loadChildren: () =>

      import('dashboard/Module').then((m) => m.DashboardModule),

  },

  { path: '**', redirectTo: 'dashboard' },

];

@NgModule({

  imports: [RouterModule.forRoot(routes)],

  exports: [RouterModule],

})

export class AppRoutingModule {}

Note: dashboard/Module is the remote entry.

Step 5: Run & Test

Run Dashboard (Remote App)

cd mfe-dashboard

npm start

Serves at: http://localhost:4201

Run Shell (Host App)

cd shell
npm start

Navigate to http://localhost:4200/dashboard — you’ll see the remote component from the dashboard app loaded

Related read: What Are Micro-Frontends And Steps To Implement Micro-Frontends In Angular

coma

Conclusion

Implementing Micro-Frontends in Angular using Module Federation offers a scalable and flexible architecture for large applications. By splitting a monolithic frontend into independently developed and deployed micro-apps, teams can work autonomously, reduce interdependencies, and accelerate delivery cycles.

Angular’s native support for Module Federation through the Angular CLI makes this approach even more accessible. Whether you’re building dashboards, admin panels, or feature-rich modules, embracing Micro-Frontends in Angular can significantly improve maintainability and collaboration across development teams.

Keep Reading

Keep Reading

A Deep Dive into Modern Clinical Workflows with AI Agents & CDS Hooks

Register Now
  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?