Skip to content

Microfrontends - Module Federation

This template demonstrates how to use Next.js Pages Router with Module Federation.

Microfrontends Module Federation Thumbnail

@vercel/microfrontends Module Federation example with Next.js Pages Router

An official Vercel example demonstrating production-ready Module Federation microfrontend architecture using Webpack's Module Federation technology.

This comprehensive example showcases how to build and deploy a Module Federation microfrontend application using @vercel/microfrontends with Module Federation and Next.js Pages Router. Learn how to architect independent, deployable frontend applications that share code at runtime while maintaining team autonomy and deployment independence.

🚀 Deploy to Vercel

Deploy each microfrontend independently to experience the full power of distributed development:

ApplicationDescriptionDeploy
RootMain shell application orchestrating federated modules
ContentContent microfrontend exposing page components
NavigationNavigation microfrontend exposing header and footer

What You'll Learn

This example demonstrates real-world Module Federation patterns and best practices:

  • 🔗 Module Federation: Share code between applications at runtime using Webpack's Module Federation
  • 🏗️ Microfrontend Architecture: Build independent applications that compose into a unified experience
  • Runtime Code Sharing: Dynamically load and share components between applications
  • 📦 Federated Components: Expose and consume React components across application boundaries
  • 🚀 Independent Deployments: Deploy each microfrontend without affecting others
  • 🎯 Team Autonomy: Enable teams to work independently while sharing code seamlessly

Understanding Module Federation

Module Federation is a Webpack technology that enables multiple separate builds to form a single application. Unlike traditional microfrontends that communicate through URLs, Module Federation allows:

  • Runtime Code Sharing: Import components from other applications at runtime
  • Shared Dependencies: Efficiently share libraries like React between applications
  • Dynamic Imports: Load federated modules on-demand for optimal performance
  • Version Management: Handle different versions of shared dependencies automatically
  • Build-time Safety: TypeScript support and compile-time checks for federated modules

Architecture Overview

This example implements a Module Federation architecture where components are shared at runtime:

Key Components

  1. Root Application (apps/root/)

    • Acts as the shell application and Module Federation container
    • Dynamically imports components from content and navigation remotes
    • Orchestrates the overall application layout and routing
    • Configures federated remotes and manages dependencies
  2. Content Application (apps/content/)

    • Exposes content-related components through Module Federation
    • Provides federated page components that can be consumed by other applications
    • Maintains its own styling and component logic
  3. Navigation Application (apps/navigation/)

    • Exposes navigation components (header and footer) through Module Federation
    • Provides reusable navigation components for the entire application
    • Manages navigation state and user interactions
  4. Shared Packages (packages/)

    • Common TypeScript configurations
    • Shared ESLint rules and formatting standards
    • Ensures consistency across all applications

Getting Started

Prerequisites

Ensure you have the following installed:

  • Node.js 20.x or later
  • pnpm 9.4.0 (recommended package manager)
  • Git for version control

Local Development Setup

  1. Clone the repository:

    git clone https://github.com/vercel-labs/microfrontends-nextjs-pages-module-federation.git
    cd microfrontends-nextjs-pages-module-federation
  2. Install dependencies:

    pnpm install
  3. Start the development environment:

    pnpm dev

    This command starts all applications simultaneously:

  4. Access the application: Open http://localhost:3024 in your browser to see the federated application where components from different microfrontends are composed together.

Project Structure Deep Dive

microfrontends-nextjs-pages-module-federation/
├── apps/
│ ├── root/ # Shell application (Module Federation container)
│ │ ├── pages/ # Next.js Pages Router
│ │ │ └── index.tsx # Composes federated components
│ │ ├── microfrontends.json # Routing configuration
│ │ ├── next.config.js # Next.js + Module Federation config
│ │ └── global.d.ts # TypeScript declarations for federated modules
│ │
│ ├── content/ # Content microfrontend (Module Federation remote)
│ │ ├── pages/
│ │ │ ├── _app.tsx # Application wrapper (exposed)
│ │ │ └── _content/
│ │ │ └── index.tsx # Content page component (exposed)
│ │ └── next.config.js # Exposes components via Module Federation
│ │
│ └── navigation/ # Navigation microfrontend (Module Federation remote)
│ ├── pages/
│ │ ├── _app.tsx # Application wrapper (exposed)
│ │ └── _navigation/
│ │ ├── header/
│ │ │ └── index.tsx # Header component (exposed)
│ │ └── footer/
│ │ └── index.tsx # Footer component (exposed)
│ └── next.config.js # Exposes navigation components
├── packages/
│ ├── eslint-config-custom/ # Shared linting configuration
│ └── ts-config/ # Shared TypeScript configuration
├── package.json # Root package.json with workspaces
├── pnpm-workspace.yaml # PNPM workspace configuration
└── turbo.json # Turborepo build pipeline

Configuration Files Explained

microfrontends.json

This file defines how microfrontends are discovered and routed:

{
"applications": {
"microfrontends-nextjs-pages-federation-root": {
"development": {
"fallback": "microfrontends-nextjs-pages-federation-root.vercel.app"
}
},
"microfrontends-nextjs-pages-federation-content": {
"routing": [{ "paths": ["/_content/:path*"] }]
},
"microfrontends-nextjs-pages-federation-navigation": {
"routing": [{ "paths": ["/_navigation/:path*"] }]
}
}
}
Module Federation Configuration

Each application has its own Next.js configuration enhanced with Module Federation:

Root Application (Container):

// apps/root/next.config.js
import { NextFederationPlugin } from '@module-federation/nextjs-mf';
const nextConfig = {
webpack(config, { isServer }) {
config.plugins.push(
new NextFederationPlugin({
name: 'root',
filename: 'static/chunks/remoteEntry.js',
remotes: {
content: `_mf_content@http://localhost:3025/_next/static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
navigation: `_mf_navigation@http://localhost:3026/_next/static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
},
}),
);
return config;
},
};

Remote Applications (Content & Navigation):

// apps/content/next.config.js
import { NextFederationPlugin } from '@module-federation/nextjs-mf';
const nextConfig = {
webpack(config, { isServer }) {
config.plugins.push(
new NextFederationPlugin({
name: '_mf_content',
filename: `static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
exposes: {
'./page': './pages/_content/index.tsx',
'./app': './pages/_app.tsx',
},
}),
);
return config;
},
};

How Module Federation Works

The magic happens through Webpack's Module Federation technology:

1. Federated Component Exposure

Remote applications expose their components through Module Federation:

// Each remote defines what components to expose
exposes: {
'./page': './pages/_content/index.tsx', // Content page
'./header': './pages/_navigation/header/index.tsx', // Header component
'./footer': './pages/_navigation/footer/index.tsx', // Footer component
'./app': './pages/_app.tsx' // App wrapper
}

2. Dynamic Component Import

The root application dynamically imports these components at runtime:

// apps/root/pages/index.tsx
import NavigationApp from 'navigation/app';
import Header from 'navigation/header';
import Footer from 'navigation/footer';
import Page from 'content/page';
import ContentApp from 'content/app';
export default function Home() {
return (
<>
<NavigationApp Component={Header} />
<ContentApp Component={Page} />
<NavigationApp Component={Footer} />
</>
);
}

3. Runtime Code Sharing

Module Federation enables:

  • Shared Dependencies: React and other libraries are shared between applications
  • Dynamic Loading: Components are loaded on-demand at runtime
  • Version Management: Handles different dependency versions automatically
  • Type Safety: TypeScript support with federated module declarations

4. Production Deployment

In production, each microfrontend is deployed independently, and Module Federation resolves the federated modules from their respective URLs.

Development Workflow

Working with Individual Microfrontends

You can develop microfrontends in isolation:

# Work on the root application only
cd apps/root
pnpm dev
# Work on the content application only
cd apps/content
pnpm dev
# Work on the navigation application only
cd apps/navigation
pnpm dev

Building and Testing

# Build all applications
pnpm build
# Run linting across all apps
pnpm lint
# Type check all applications
pnpm typecheck
# Run all quality checks
pnpm checks

Adding New Federated Components

  1. Create the component in your remote application
  2. Expose it through Module Federation in next.config.js:
    exposes: {
    './newComponent': './path/to/component.tsx'
    }
  3. Add TypeScript declarations in the container app's global.d.ts:
    declare module 'remoteName/newComponent' {
    const Component: React.ComponentType;
    export default Component;
    }
  4. Import and use in the container application:
    import NewComponent from 'remoteName/newComponent';

Deployment Strategy

Independent Deployment Benefits

Each microfrontend can be deployed independently, enabling:

  • Faster deployments: Only the changed microfrontend needs redeployment
  • Reduced risk: Deployments are isolated and can't break other parts
  • Team autonomy: Teams can deploy on their own schedule
  • Rollback flexibility: Roll back individual microfrontends without affecting others

Vercel Configuration

Each application includes optimized Vercel configuration:

  • Framework detection: Automatic Next.js optimization
  • Build settings: Turborepo-aware build commands with Module Federation support
  • Environment variables: Proper environment isolation
  • Edge functions: Optimal performance at the edge

Best Practices Implemented

🎯 Consistent Development Experience

  • Shared TypeScript configuration ensures type safety across all federated modules
  • Common ESLint rules maintain code quality standards
  • Unified prettier configuration for consistent formatting

🔧 Build Optimization

  • Turborepo orchestrates builds efficiently with caching
  • Module Federation optimizes shared dependencies automatically
  • Independent builds enable faster CI/CD pipelines

🎨 UI Consistency

  • Shared component patterns across federated modules
  • Consistent design tokens and styling approach
  • Federated components maintain design system compliance

🚀 Performance Optimization

  • Code splitting at the microfrontend level with Module Federation
  • Shared chunk optimization for common dependencies
  • Runtime loading optimization for federated modules

Advanced Features

TypeScript Support for Federated Modules

The project includes comprehensive TypeScript support:

// apps/root/global.d.ts
declare module 'navigation/header' {
const Header: React.ComponentType;
export default Header;
}
declare module 'navigation/footer' {
const Footer: React.ComponentType;
export default Footer;
}
declare module 'content/page' {
const Page: React.ComponentType;
export default Page;
}

Vercel Toolbar Integration

Development builds include the Vercel Toolbar for enhanced debugging:

  • Visual indicators of federated module boundaries
  • Performance metrics for federated components
  • Real-time module loading analytics

Error Boundaries and Fallbacks

Built-in error handling for federated components:

  • Graceful degradation when remote modules fail to load
  • Isolated error reporting per microfrontend
  • Fallback components for improved user experience

Troubleshooting

Common Issues and Solutions

Module Federation loading errors:

# Ensure all applications are running
pnpm dev
# Check that remoteEntry.js files are accessible
curl http://localhost:3025/_next/static/chunks/remoteEntry.js

TypeScript errors with federated modules:

# Verify TypeScript declarations in global.d.ts
# Ensure module names match the federation configuration

Build failures:

# Run type checking to identify issues
pnpm typecheck
# Verify all federated modules are built correctly
pnpm build

Port conflicts during development:

# Kill processes using the required ports
npx kill-port 3024 3025 3026
pnpm dev

Module Federation vs Multi-Zone

This example uses Module Federation for runtime code sharing, which differs from multi-zone architecture:

FeatureModule FederationMulti-Zone
Code SharingRuntime component sharingURL-based routing
Bundle SizeShared dependenciesIndependent bundles
IntegrationComponent-level integrationPage-level integration
ComplexityHigher (runtime loading)Lower (URL routing)
Use CaseShared UI componentsIndependent applications

Choose Module Federation when you need to share React components between applications. Choose multi-zone when you need independent applications with URL-based routing.

📚 Documentation

Microfrontends Module Federation Thumbnail

Microfrontends - Module Federation

This template demonstrates how to use Next.js Pages Router with Module Federation.

@vercel/microfrontends Module Federation example with Next.js Pages Router

An official Vercel example demonstrating production-ready Module Federation microfrontend architecture using Webpack's Module Federation technology.

This comprehensive example showcases how to build and deploy a Module Federation microfrontend application using @vercel/microfrontends with Module Federation and Next.js Pages Router. Learn how to architect independent, deployable frontend applications that share code at runtime while maintaining team autonomy and deployment independence.

🚀 Deploy to Vercel

Deploy each microfrontend independently to experience the full power of distributed development:

ApplicationDescriptionDeploy
RootMain shell application orchestrating federated modules
ContentContent microfrontend exposing page components
NavigationNavigation microfrontend exposing header and footer

What You'll Learn

This example demonstrates real-world Module Federation patterns and best practices:

  • 🔗 Module Federation: Share code between applications at runtime using Webpack's Module Federation
  • 🏗️ Microfrontend Architecture: Build independent applications that compose into a unified experience
  • Runtime Code Sharing: Dynamically load and share components between applications
  • 📦 Federated Components: Expose and consume React components across application boundaries
  • 🚀 Independent Deployments: Deploy each microfrontend without affecting others
  • 🎯 Team Autonomy: Enable teams to work independently while sharing code seamlessly

Understanding Module Federation

Module Federation is a Webpack technology that enables multiple separate builds to form a single application. Unlike traditional microfrontends that communicate through URLs, Module Federation allows:

  • Runtime Code Sharing: Import components from other applications at runtime
  • Shared Dependencies: Efficiently share libraries like React between applications
  • Dynamic Imports: Load federated modules on-demand for optimal performance
  • Version Management: Handle different versions of shared dependencies automatically
  • Build-time Safety: TypeScript support and compile-time checks for federated modules

Architecture Overview

This example implements a Module Federation architecture where components are shared at runtime:

Key Components

  1. Root Application (apps/root/)

    • Acts as the shell application and Module Federation container
    • Dynamically imports components from content and navigation remotes
    • Orchestrates the overall application layout and routing
    • Configures federated remotes and manages dependencies
  2. Content Application (apps/content/)

    • Exposes content-related components through Module Federation
    • Provides federated page components that can be consumed by other applications
    • Maintains its own styling and component logic
  3. Navigation Application (apps/navigation/)

    • Exposes navigation components (header and footer) through Module Federation
    • Provides reusable navigation components for the entire application
    • Manages navigation state and user interactions
  4. Shared Packages (packages/)

    • Common TypeScript configurations
    • Shared ESLint rules and formatting standards
    • Ensures consistency across all applications

Getting Started

Prerequisites

Ensure you have the following installed:

  • Node.js 20.x or later
  • pnpm 9.4.0 (recommended package manager)
  • Git for version control

Local Development Setup

  1. Clone the repository:

    git clone https://github.com/vercel-labs/microfrontends-nextjs-pages-module-federation.git
    cd microfrontends-nextjs-pages-module-federation
  2. Install dependencies:

    pnpm install
  3. Start the development environment:

    pnpm dev

    This command starts all applications simultaneously:

  4. Access the application: Open http://localhost:3024 in your browser to see the federated application where components from different microfrontends are composed together.

Project Structure Deep Dive

microfrontends-nextjs-pages-module-federation/
├── apps/
│ ├── root/ # Shell application (Module Federation container)
│ │ ├── pages/ # Next.js Pages Router
│ │ │ └── index.tsx # Composes federated components
│ │ ├── microfrontends.json # Routing configuration
│ │ ├── next.config.js # Next.js + Module Federation config
│ │ └── global.d.ts # TypeScript declarations for federated modules
│ │
│ ├── content/ # Content microfrontend (Module Federation remote)
│ │ ├── pages/
│ │ │ ├── _app.tsx # Application wrapper (exposed)
│ │ │ └── _content/
│ │ │ └── index.tsx # Content page component (exposed)
│ │ └── next.config.js # Exposes components via Module Federation
│ │
│ └── navigation/ # Navigation microfrontend (Module Federation remote)
│ ├── pages/
│ │ ├── _app.tsx # Application wrapper (exposed)
│ │ └── _navigation/
│ │ ├── header/
│ │ │ └── index.tsx # Header component (exposed)
│ │ └── footer/
│ │ └── index.tsx # Footer component (exposed)
│ └── next.config.js # Exposes navigation components
├── packages/
│ ├── eslint-config-custom/ # Shared linting configuration
│ └── ts-config/ # Shared TypeScript configuration
├── package.json # Root package.json with workspaces
├── pnpm-workspace.yaml # PNPM workspace configuration
└── turbo.json # Turborepo build pipeline

Configuration Files Explained

microfrontends.json

This file defines how microfrontends are discovered and routed:

{
"applications": {
"microfrontends-nextjs-pages-federation-root": {
"development": {
"fallback": "microfrontends-nextjs-pages-federation-root.vercel.app"
}
},
"microfrontends-nextjs-pages-federation-content": {
"routing": [{ "paths": ["/_content/:path*"] }]
},
"microfrontends-nextjs-pages-federation-navigation": {
"routing": [{ "paths": ["/_navigation/:path*"] }]
}
}
}
Module Federation Configuration

Each application has its own Next.js configuration enhanced with Module Federation:

Root Application (Container):

// apps/root/next.config.js
import { NextFederationPlugin } from '@module-federation/nextjs-mf';
const nextConfig = {
webpack(config, { isServer }) {
config.plugins.push(
new NextFederationPlugin({
name: 'root',
filename: 'static/chunks/remoteEntry.js',
remotes: {
content: `_mf_content@http://localhost:3025/_next/static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
navigation: `_mf_navigation@http://localhost:3026/_next/static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
},
}),
);
return config;
},
};

Remote Applications (Content & Navigation):

// apps/content/next.config.js
import { NextFederationPlugin } from '@module-federation/nextjs-mf';
const nextConfig = {
webpack(config, { isServer }) {
config.plugins.push(
new NextFederationPlugin({
name: '_mf_content',
filename: `static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
exposes: {
'./page': './pages/_content/index.tsx',
'./app': './pages/_app.tsx',
},
}),
);
return config;
},
};

How Module Federation Works

The magic happens through Webpack's Module Federation technology:

1. Federated Component Exposure

Remote applications expose their components through Module Federation:

// Each remote defines what components to expose
exposes: {
'./page': './pages/_content/index.tsx', // Content page
'./header': './pages/_navigation/header/index.tsx', // Header component
'./footer': './pages/_navigation/footer/index.tsx', // Footer component
'./app': './pages/_app.tsx' // App wrapper
}

2. Dynamic Component Import

The root application dynamically imports these components at runtime:

// apps/root/pages/index.tsx
import NavigationApp from 'navigation/app';
import Header from 'navigation/header';
import Footer from 'navigation/footer';
import Page from 'content/page';
import ContentApp from 'content/app';
export default function Home() {
return (
<>
<NavigationApp Component={Header} />
<ContentApp Component={Page} />
<NavigationApp Component={Footer} />
</>
);
}

3. Runtime Code Sharing

Module Federation enables:

  • Shared Dependencies: React and other libraries are shared between applications
  • Dynamic Loading: Components are loaded on-demand at runtime
  • Version Management: Handles different dependency versions automatically
  • Type Safety: TypeScript support with federated module declarations

4. Production Deployment

In production, each microfrontend is deployed independently, and Module Federation resolves the federated modules from their respective URLs.

Development Workflow

Working with Individual Microfrontends

You can develop microfrontends in isolation:

# Work on the root application only
cd apps/root
pnpm dev
# Work on the content application only
cd apps/content
pnpm dev
# Work on the navigation application only
cd apps/navigation
pnpm dev

Building and Testing

# Build all applications
pnpm build
# Run linting across all apps
pnpm lint
# Type check all applications
pnpm typecheck
# Run all quality checks
pnpm checks

Adding New Federated Components

  1. Create the component in your remote application
  2. Expose it through Module Federation in next.config.js:
    exposes: {
    './newComponent': './path/to/component.tsx'
    }
  3. Add TypeScript declarations in the container app's global.d.ts:
    declare module 'remoteName/newComponent' {
    const Component: React.ComponentType;
    export default Component;
    }
  4. Import and use in the container application:
    import NewComponent from 'remoteName/newComponent';

Deployment Strategy

Independent Deployment Benefits

Each microfrontend can be deployed independently, enabling:

  • Faster deployments: Only the changed microfrontend needs redeployment
  • Reduced risk: Deployments are isolated and can't break other parts
  • Team autonomy: Teams can deploy on their own schedule
  • Rollback flexibility: Roll back individual microfrontends without affecting others

Vercel Configuration

Each application includes optimized Vercel configuration:

  • Framework detection: Automatic Next.js optimization
  • Build settings: Turborepo-aware build commands with Module Federation support
  • Environment variables: Proper environment isolation
  • Edge functions: Optimal performance at the edge

Best Practices Implemented

🎯 Consistent Development Experience

  • Shared TypeScript configuration ensures type safety across all federated modules
  • Common ESLint rules maintain code quality standards
  • Unified prettier configuration for consistent formatting

🔧 Build Optimization

  • Turborepo orchestrates builds efficiently with caching
  • Module Federation optimizes shared dependencies automatically
  • Independent builds enable faster CI/CD pipelines

🎨 UI Consistency

  • Shared component patterns across federated modules
  • Consistent design tokens and styling approach
  • Federated components maintain design system compliance

🚀 Performance Optimization

  • Code splitting at the microfrontend level with Module Federation
  • Shared chunk optimization for common dependencies
  • Runtime loading optimization for federated modules

Advanced Features

TypeScript Support for Federated Modules

The project includes comprehensive TypeScript support:

// apps/root/global.d.ts
declare module 'navigation/header' {
const Header: React.ComponentType;
export default Header;
}
declare module 'navigation/footer' {
const Footer: React.ComponentType;
export default Footer;
}
declare module 'content/page' {
const Page: React.ComponentType;
export default Page;
}

Vercel Toolbar Integration

Development builds include the Vercel Toolbar for enhanced debugging:

  • Visual indicators of federated module boundaries
  • Performance metrics for federated components
  • Real-time module loading analytics

Error Boundaries and Fallbacks

Built-in error handling for federated components:

  • Graceful degradation when remote modules fail to load
  • Isolated error reporting per microfrontend
  • Fallback components for improved user experience

Troubleshooting

Common Issues and Solutions

Module Federation loading errors:

# Ensure all applications are running
pnpm dev
# Check that remoteEntry.js files are accessible
curl http://localhost:3025/_next/static/chunks/remoteEntry.js

TypeScript errors with federated modules:

# Verify TypeScript declarations in global.d.ts
# Ensure module names match the federation configuration

Build failures:

# Run type checking to identify issues
pnpm typecheck
# Verify all federated modules are built correctly
pnpm build

Port conflicts during development:

# Kill processes using the required ports
npx kill-port 3024 3025 3026
pnpm dev

Module Federation vs Multi-Zone

This example uses Module Federation for runtime code sharing, which differs from multi-zone architecture:

FeatureModule FederationMulti-Zone
Code SharingRuntime component sharingURL-based routing
Bundle SizeShared dependenciesIndependent bundles
IntegrationComponent-level integrationPage-level integration
ComplexityHigher (runtime loading)Lower (URL routing)
Use CaseShared UI componentsIndependent applications

Choose Module Federation when you need to share React components between applications. Choose multi-zone when you need independent applications with URL-based routing.

📚 Documentation

Unleash New Possibilities

Deploy your app on Vercel and unlock its full potential

Try Vercel Free