VOOZH about

URL: https://dzone.com/articles/micro-frontends-in-angular-and-react-a-deep-techni

⇱ Micro Frontends in Angular & React: A Deep Technical Guide


Related

  1. DZone
  2. Coding
  3. JavaScript
  4. Micro Frontends in Angular and React: A Deep Technical Guide for Scalable Front-End Architecture

Micro Frontends in Angular and React: A Deep Technical Guide for Scalable Front-End Architecture

Module Federation, Custom Elements, and orchestrators like Single-SPA enable independently evolving, maintainable applications with a seamless user experience.

Likes
Comment
Save
3.2K Views

Join the DZone community and get the full member experience.

Join For Free

Micro-frontends allow large teams to build independent UI modules that ship autonomously. Angular and React both support micro-frontend architecture using Webpack Module Federation. Angular benefits from strong structure and RxJS-based shared services, while React provides lightweight, flexible federated components. A hybrid Angular-React MFE system typically follows a shell-and-remotes architecture, with shared libraries, version-safe dependencies, and independent deployments.

What Micro Frontends Are (and Why They Matter)

Micro frontends split a large UI into independently developed and deployed applications that compose together at runtime.

Problems They Solve

  • Long build & deployment pipelines for monolithic front-end apps
  • Cross-team dependency conflicts and tight coupling
  • Risky framework upgrades
  • Difficulty scaling engineering teams
  • Slow feature delivery due to centralized release cycles

Benefits

  • Independent deployments
  • Technology freedom (Angular + React = no problem)
  • Smaller, maintainable codebases
  • Domain ownership
  • Easier migrations

Macro Architecture Overview

JavaScript
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ SHELL β”‚
 β”‚ Global Nav, Routing, Auth, Layout β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ β”‚ β”‚
 β–Ό β–Ό β–Ό
Angular MFE React MFE React/Angular MFE
/orders /dashboard /profile
Module Federation Module Federation Custom Elements


Folder Structure for Enterprise-Scale MFEs

A poly-repo style (common in enterprises):

JavaScript
microfrontends/
β”‚
β”œβ”€β”€ shell/ # Shell app (Angular or React)
β”‚ β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ webpack.config.js
β”‚ └── package.json
β”‚
β”œβ”€β”€ mfe-angular-orders/
β”‚ β”œβ”€β”€ src/app/orders/
β”‚ β”œβ”€β”€ src/app/app.module.ts
β”‚ β”œβ”€β”€ webpack.config.js
β”‚ └── package.json
β”‚
β”œβ”€β”€ mfe-react-dashboard/
β”‚ β”œβ”€β”€ src/Dashboard.jsx
β”‚ β”œβ”€β”€ webpack.config.js
β”‚ └── package.json
β”‚
└── mfe-react-profile/
 β”œβ”€β”€ src/Profile.jsx
 β”œβ”€β”€ webpack.config.js
 └── package.json


Monorepo with Nx

JavaScript
apps/
 shell/
 mfe-orders/
 mfe-dashboard/
 mfe-profile/
libs/
 shared-ui/
 auth/
 utils/


Nx simplifies dependency graphs, CI/CD, caching, and workspace generators.

Angular Micro Frontend Example (Module Federation)

Angular MFE (Orders App)

webpack.config.js

JavaScript
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const { share } = require("@angular-architects/module-federation/webpack");

module.exports = {
 output: {
 uniqueName: "orders",
 },
 plugins: [
 new ModuleFederationPlugin({
 name: "orders",
 filename: "remoteEntry.js",
 exposes: {
 "./OrdersModule": "./src/app/orders/orders.module.ts",
 },
 shared: share({
 "@angular/core": { singleton: true, strictVersion: true },
 "@angular/common": { singleton: true },
 "@angular/router": { singleton: true },
 }),
 })
 ],
};


Angular Shell Loads the Orders Module

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

JavaScript
const routes: Routes = [
 {
 path: "orders",
 loadChildren: () =>
 loadRemoteModule({
 type: "module",
 remoteEntry: "http://localhost:4201/remoteEntry.js",
 exposedModule: "./OrdersModule",
 }).then(m => m.OrdersModule),
 },
];


Angular Orders Component Example

orders.component.ts

JavaScript
@Component({
 selector: 'app-orders',
 template: `
 <h2>Orders</h2>
 <ul>
 <li *ngFor="let order of orders">{{ order.id }} - {{ order.status }}</li>
 </ul>
 `
})
export class OrdersComponent {
 orders = [
 { id: 101, status: 'Shipped' },
 { id: 102, status: 'Processing' },
 ];
}


React Micro Frontend Example (Module Federation)

React Dashboard MFE

mfe-react-dashboard/webpack.config.js

JavaScript
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
 plugins: [
 new ModuleFederationPlugin({
 name: "dashboard",
 filename: "remoteEntry.js",
 exposes: {
 "./Dashboard": "./src/Dashboard.jsx",
 },
 shared: ["react", "react-dom"],
 }),
 ],
};


React Dashboard Component

JavaScript
export default function Dashboard() {
 return (
 <div>
 <h2>Analytics Dashboard</h2>
 <p>Live metrics will appear here...</p>
 </div>
 );
}


Angular Shell Loading React Components

Step 1: React Render Wrapper

shell/src/app/react-renderer.ts

JavaScript
import React from "react";
import ReactDOM from "react-dom";

export function mountReact(Component: any, elementId: string) {
 ReactDOM.render(<Component />, document.getElementById(elementId));
}


Step 2: Wrapper Component in Angular

JavaScript
@Component({
 selector: 'app-dashboard-wrapper',
 template: `<div id="dashboard-root"></div>`
})
export class DashboardWrapper implements AfterViewInit {
 async ngAfterViewInit() {
 const Dashboard = (await import("dashboard/Dashboard")).default;
 mountReact(Dashboard, "dashboard-root");
 }
}


Step 3: Routing

JavaScript
{
 path: 'dashboard',
 component: DashboardWrapper
}


The result? Beautiful Angular + React harmony.


React Shell Consuming Angular MFE

Angular MFE can be delivered as a Custom Element.

Angular MFE Exports a Web Component

JavaScript
import { createCustomElement } from '@angular/elements';
import { OrdersComponent } from './orders.component';

const ordersElement = createCustomElement(OrdersComponent, { injector });
customElements.define('orders-widget', ordersElement);

React Shell Uses It Natively

JavaScript
function App() {
 return (
 <div>
 <h2>User Profile</h2>
 <orders-widget></orders-widget>
 </div>
 );
}


Communication Between Micro Frontends

Communication is challenging in MFEs because apps must stay decoupled.

Event Bus Pattern

Use browser events:

JavaScript
window.dispatchEvent(new CustomEvent("cart:updated", { detail: count }));

Listener:

JavaScript
window.addEventListener("cart:updated", (e) => console.log(e.detail));


Cross-MFE Shared Store (exposed via Module Federation)

React Exports:

JavaScript
exposes: { "./store": "./src/store.js" }

Angular Imports:

JavaScript
const store = await import("dashboard/store");
store.subscribe(value => ...);


URL-based Communication

The following are used by apps like Amazon to communicate state.

  • Route parameters
  • Query params
  • URL fragments

Deployment Patterns

Independent Deployments (Best Practice)

Every MFE deploys separately.

JavaScript
https://app.company.com/
https://orders.company.com/
https://dashboard.company.com/
https://profile.company.com/

Shell dynamically loads remoteEntry URLs.

CI/CD Workflow Example

  • Lint β†’ Test β†’ Build
  • Upload artifacts to S3 or CDN
  • Shell periodically fetches updated remoteEntry.json
  • Cache-busting via content hashes

Best Practices (Critical for Enterprise)

Keep MFEs small

Each app should represent a business domain.

Do not share too many libraries

This creates coupling.

Prefer runtime federation over build-time federation

Gives true deployment independence.

Add a versioning strategy for remotes

Prevent breaking shells.

Use monorepo (Nx) if teams share code

Use poly-repo if independence is priority.

Common Anti-Patterns

❌ Using iFrames for everything
❌ Sharing global state directly
❌ Hard-coding remote URLs in the shell
❌ Putting multiple business domains in one MFE
❌ Rebuilding the shell for every MFE change

When to Use Micro Frontends (and When Not To)

Use MFEs if:

βœ” Your team is large (50+ engineers)
βœ” Multiple frameworks are involved
βœ” Release cycles must be independent
βœ” You need long-term migration flexibility

Avoid MFEs if:

✘ You have a small app (< 10 engineers)
✘ You don’t have strong DevOps support
✘ Performance is a bigger priority than autonomy

Conclusion

Micro frontends offer a robust, scalable architecture for modern front-end developmentβ€”especially for enterprise teams using Angular, React, or both. Using Module Federation, Custom Elements, and orchestrators like Single-SPA, companies can build maintainable, future-proof applications that evolve independently while delivering a seamless experience.

While Angular provides strong module boundaries and stable typing, React offers flexibility and a lightweight component-based architecture.

Combined, they form a powerful cross-framework ecosystem that supports large-scale innovation.

JavaScript React (JavaScript library)

Opinions expressed by DZone contributors are their own.

Related

  • How We Reduced LCP by 75% in a Production React App
  • Production-Grade React Project Structure: From Setup to Scale
  • Build a Face-Matching ID Scanner With ReactJS and AI
  • Tuples and Records (Part 3): Potential ECMAScript Proposals

Partner Resources

Γ—

Comments

The likes didn't load as expected. Please refresh the page and try again.

Let's be friends: