Micro Frontend with Angular
Here is a step by step guide to create a Micro Frontend Architecture with Angular 19
1. Overview of Micro-Frontends in Angular
A micro-frontend architecture splits a larger application into distinct, smaller front-end apps (micro-apps), each focusing on a specific business domain. These micro-apps can be developed, deployed, and maintained independently, allowing for:
Scalability: Teams can work on different micro-frontends in parallel.
Flexibility: Each micro-frontend can use a different Angular version (though ideally kept in sync) or even a different front-end framework (if using single-spa or a similar solution).
Autonomous deployments: Teams can release features independently.
Popular Approaches in Angular
Webpack 5 Module Federation:
A built-in feature of Webpack 5, which lets you dynamically load code from other bundles at runtime.
Recommended for an Angular CLI 19+.
single-spa:
A micro-frontend framework that supports multiple front-end technologies (Angular, React, Vue, etc.) under a single “root” config.
Typically used if you have heterogeneous tech stacks or want framework-agnostic micro-frontends.
Custom Solutions:
Using iframes or custom build processes.
Generally less recommended because of complexity and integration difficulties.
In this guide, we focus on Module Federation, which has become the de facto approach in many Angular micro-frontend setups.
2. Setting Up the Host (Shell) Application
Install Angular CLI (if not already installed)
npm install -g @angular/cli
Create a new Angular workspace (or you can use an existing one):
ng new microfrontend-demo --create-application=false
The --create-application=false flag creates an empty workspace with no default application.
Generate the host application:
cd microfrontend-demo ng generate application shell
- shell is the name of the host (base) app.
Generate the Micro Frontends inside the same workspace
ng generate application microA ng generate application microB
Add the module Federation Package for the three applications, i.e (Shell, microA, and miccroB)
// For the Shell use this command to get a shell Module federation setup for it, ng add @angular-architects/module-federation --project shell --port 4200 --type dynamic-host // Then for the other applications, use the commands below to get their module federation setups ng add @angular-architects/module-federation --project microA --port 420 1 --type remote ng add @angular-architects/module-federation --project microB --port 420 2 --type remote
Make the Module Federation in the shell to detect the other Applications
Go to the public folder in the shell application and find the mf.manifest.json file, Here is where you add application and it’s remoteEntry and port to start anytime a new application is added, by default you might see a setup like this in the file{ "mfe": "http://localhost:4200/remoteEntry.js" } // change it to fit your own Application { "microA": "http://localhost:4201/remoteEntry.js", "microB": "http://localhost:4202/remoteEntry.js" }
Setup the app.routes.ts in the shell to dynamically load the micro frontends in the Application workspace
import { loadRemoteModule } from '@angular-architects/module-federation'; import { Routes } from '@angular/router'; export const routes: Routes = [ { path: 'microA', loadComponent: () => loadRemoteModule('dashboard', './Component').then((m) => m.AppComponent), }, { path: 'microB', loadComponent: () => loadRemoteModule('user', './Component').then((m) => m.AppComponent), }, ];
Run the applications and dynamically route to the micro frontends
// run these commands to start up all the micro frontends ng s shell ng s microA ng s microB
These commands will run the shell on port 4200, the microA on port 4201, and the microB on port 4202
Now try going to http://localhost:4200, or http://localhost:4200/microA or http://localhost:4200/microB
you’ll now see that your micro frontends are all being dynamically loaded into the shell applicattion although they are running on seperate ports