This template demonstrates how to build Vite + React microfrontends with Single SPA.
Using this example, you can learn how to set up a microfrontend using single-spa with Module Federation on Vercel. This example demonstrates how to create a microfrontend architecture that allows you to load multiple applications in a single page, enabling independent deployments and development.
The example is available on GitHub at vercel-labs/microfrontends-single-spa-module-federation.
This example demonstrates real-world microfrontend patterns and best practices:
This example implements a hybrid architecture combining single-spa for application orchestration with Module Federation for runtime code sharing:
Root Application (apps/root/
)
Content Application (apps/content/
)
Navigation Application (apps/navigation/
)
Shared Packages (packages/
)
This hybrid approach provides:
To run the example, you will need the following prerequisites:
It is also recommended to have:
Follow these steps to set up the example on your local machine. Make sure you have the prerequisites installed before proceeding.
Clone the repository:
git clone https://github.com/vercel-labs/microfrontends-single-spa-module-federation.gitcd microfrontends-single-spa-module-federation
Install dependencies:
pnpm install
Start the development environment:
pnpm dev
This command starts all applications simultaneously:
Access the application:
Open http://localhost:3024 in your browser to see the federated application where components from different microfrontends are composed together using single-spa and Module Federation.
This example uses the following technologies:
The microfrontends are configured using the microfrontends.json
file. This file defines the applications and their routing. The example uses the following configuration:
// apps/root/microfrontends.json{"$schema": "https://openapi.vercel.sh/microfrontends.json","applications": {"microfrontends-single-spa-module-federation-root": {"development": {"fallback": "microfrontends-single-spa-module-federation-root.vercel.app",},},"microfrontends-single-spa-module-federation-content": {"routing": [{"paths": ["/_content/:path*"],},],},"microfrontends-single-spa-module-federation-navigation": {"routing": [{"paths": ["/_navigation/:path*"],},],},},}
This configuration is defined in the root application, which is the default application of the microfrontends group. The microfrontends.json
file specifies the applications and their routing paths. The development.fallback
field is used to specify a fallback URL. See more details on how to manage your microfrontends in the Managing Microfrontends documentation.
The microfrontends.json
in this example defines three applications:
microfrontends-single-spa-module-federation-root
: The root application that serves as the entry point for the microfrontend architecture. This is the default application of the Microfrontends group.microfrontends-single-spa-module-federation-content
: A microfrontend application that handles content-related functionality. It is routed to paths starting with /_content/
. The application will provide the landing page content for our example.microfrontends-single-spa-module-federation-navigation
: A microfrontend application that handles navigation functionality. It is routed to paths starting with /_navigation/
. The application will provide the navigation components.As we don't specify a specific local Microfrontends proxy port, the local Microfrontends proxy will run on port 3024
by default. You can change this by setting localProxyPort
in the microfrontends.json
file.
To make Microfrontends and Module Federation work, we need to configure Vite in each microfrontend application.
For the navigation
and content
applications providing the Module Federation remotes for the root application, we need to set up the Vite configuration as follows:
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends({basePath: '/_navigation',}) as Plugin,react(),federation({name: 'navigation',manifest: true,filename: 'remoteEntry.js',exposes: {'./header': './src/header/index.tsx','./footer': './src/footer/index.tsx',},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
The only difference between the navigation
and content
applications is the basePath
in the microfrontends
plugin configuration, the name of the Module Federation remote and the exposed modules. The basePath
is set to /_navigation
for the navigation
application and to /_content
for the content
application.
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends({basePath: '/_content',}) as Plugin,react(),federation({name: 'content',manifest: true,filename: 'remoteEntry.js',exposes: {'./landing': './src/landing.tsx',},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
Both configurations use the @module-federation/vite
plugin to set up Module Federation and the @vercel/microfrontends/experimental/vite
plugin to enable microfrontends support. The federation
plugin is used to expose the components of the microfrontend applications, while the microfrontends
plugin is used to configure the base path for the microfrontend routing.
For both the navigation
and content
applications, we expose the components that will be used by the root application. The navigation
application exposes a header and footer component, while the content
application exposes a landing component.
React and React DOM are shared as singletons to ensure that the same instance is used across the microfrontends. This is important for maintaining a consistent state and avoiding issues with multiple instances of React.
The additional specification for a build.target
is set to chrome89
to ensure compatibility with the features used in the microfrontends. In this case we need top-level await support, which is available in Chrome 89 and later.
For the root application, we need to set up the Vite configuration to load the microfrontends and use the exposed components from the navigation
and content
applications:
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import { vercelToolbar } from '@vercel/toolbar/plugins/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends() as Plugin,vercelToolbar(),react(),federation({name: 'root',manifest: true,remotes: {navigation: {type: 'module',name: 'navigation',entry: '/_navigation/remoteEntry.js',},content: {type: 'module',name: 'content',entry: '/_content/remoteEntry.js',},},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
The root application doesn't expose any components, but it loads the navigation
and content
applications as remotes using Module Federation. The remotes
configuration specifies the entry points for the remote applications, which are the remoteEntry.js
files exposed by the navigation
and content
applications.
As we are using Vite for the navigation
and content
applications providing the Module Federation remotes, we use remotes specified with type: 'module'
to load the remote applications. This allows us to use the native ES module loading capabilities of the browser, which is supported by Vite.
The entry paths for the remotes are set to /_navigation/remoteEntry.js
and /_content/remoteEntry.js
, which correspond to the base paths defined in the microfrontends.json
file. As we are using Vercel Microfrontends solution and in this example we are using client-side rendering, we can use relative URLs for the remotes. This allows the root application to dynamically load the components from the navigation
and content
applications at runtime. The routing will be managed by Vercel Microfrontends, which will ensure that the correct application is loaded based on the path.
The root application is the entry point for the microfrontend architecture. It is responsible for loading the navigation
and content
remotes and rendering their components as single-spa applications.
To create a layout for the root application using single-spa, we can use the following HTML structure:
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Company Landing Page</title><link rel="stylesheet" href="./src/globals.css" /><script type="module" src="./src/index.ts"></script></head><body className="flex min-h-screen flex-col"><div id="single-spa-application:header"></div><div id="single-spa-application:content"></div><div id="single-spa-application:footer"></div></body></html>
To register each application with single-spa, we can use the following code in the src/index.ts
file of the root application:
import { mountVercelToolbar } from '@vercel/toolbar/vite';import { registerApplication, start } from 'single-spa';import './globals.css';registerApplication('header',() => import('navigation/header'),() => true,);registerApplication('footer',() => import('navigation/footer'),() => true,);registerApplication('content',() => import('content/landing'),() => true,);start();mountVercelToolbar();
We register each single-spa application using the registerApplication
function. Each application is registered with a name, a loading function that imports the remote component using dynamic ES module import, and an activity function that determines when the application should be active based on the current route, which will be always true in the case of this example.
In the remote applications, we are using single-spa-react
to create a React component that will be rendered by single-spa. The content
application provides the main page content, while the navigation
application provides the header and footer components.
We need to define the bootstrap
, mount
, and unmount
functions for each component. These functions are used by single-spa to manage the lifecycle of the applications.
import React from 'react';import ReactDOMClient from 'react-dom/client';import singleSpaReact from 'single-spa-react';import './globals.css';function Landing(): React.JSX.Element {return <>{/* ... */}</>;}export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Landing,errorBoundary() {return <></>;},});
For the navigation
application, we define the header and footer components similarly.
// ...export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Header,errorBoundary() {return <></>;},});
// ...export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Footer,errorBoundary() {return <></>;},});
The difference being which rootComponent
is used for each application. The Landing
component in the content
application, and the Header
and Footer
components in the navigation
application.
With everything needed set up, you can now run the microfrontend applications locally. The root application will be available at http://localhost:3024
, and it will load the content
and navigation
applications as microfrontends.
To start a development server for each application, we use a dev
npm script in each application's package.json
file. The dev
script uses Vite to start the development server for the application and also specifies the port to run on when using the Microfrontends proxy.
// apps/root/package.json{"scripts": {"build": "vite build","dev": "vite --port $(microfrontends port)","start": "vite preview --port $(microfrontends port)",},}
Run the following command in the root directory of the cloned repository to start the development server and the Microfrontends proxy:
pnpm dev
This command will start all the applications in the monorepo and also starts the Microfrontends proxy on port 3024
.
Deploy each microfrontend independently to experience the full power of distributed development:
Each microfrontend can be deployed independently, enabling:
Fork the repository: Create your own copy of the repository on GitHub.
Set up Vercel projects: Create separate Vercel projects for each microfrontend:
root
, content
, navigation
)apps/root
, apps/content
, apps/navigation
)Configure Microfrontends group:
Environment configuration:
microfrontends.json
file is properly configuredDeploy and verify:
Each application includes optimized Vercel configuration:
Once deployed, your applications will be accessible at URLs similar to:
https://your-root-app.vercel.app
https://your-content-app.vercel.app
https://your-navigation-app.vercel.app
The root application will automatically load the content and navigation microfrontends based on the routing configuration in microfrontends.json
.
The example is deployed to Vercel at https://vercel-microfrontends-single-spa.vercel.app already for you to check out.
You can develop microfrontends in isolation:
# Work on the root application onlycd apps/rootpnpm dev# Work on the content application onlycd apps/contentpnpm dev# Work on the navigation application onlycd apps/navigationpnpm dev
# Build all applicationspnpm build# Run linting across all appspnpm lint# Type check all applicationspnpm typecheck# Run all quality checkspnpm checks
vite.config.ts
:
exposes: {'./newComponent': './src/path/to/component.tsx'}
global.d.ts
:
declare module 'remoteName/newComponent' {const Component: React.ComponentType;export default Component;}
import NewComponent from 'remoteName/newComponent';
Module Federation loading errors:
# Ensure all applications are runningpnpm dev
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 issuespnpm typecheck# Verify all federated modules are built correctlypnpm build
This example combines both single-spa and Module Federation for optimal microfrontend architecture:
Feature | single-spa | Module Federation | Combined Approach |
---|---|---|---|
Component Sharing | URL-based routing | Runtime code sharing | Both runtime sharing and routing |
Bundle Size | Independent bundles | Shared dependencies | Optimized shared dependencies |
Integration | Application-level | Component-level | Multi-level integration |
Lifecycle Management | Built-in lifecycle | Manual lifecycle | single-spa manages MF components |
Use Case | App orchestration | Code sharing | Complete microfrontend solution |
Benefits of the combined approach:
The Vercel Toolbar is included in the root application to provide insights and debugging capabilities for the microfrontend applications. The toolbar can be mounted using the mountVercelToolbar
function from the @vercel/toolbar/vite
package.
Learn more about the Vercel Toolbar in the Vercel Toolbar documentation.
This example demonstrates how to set up a microfrontend architecture using single-spa with Module Federation on Vercel. By following the steps outlined in this guide and the provided repo on GitHub, you can create a scalable and maintainable microfrontend application that allows for independent deployments and development.
This template demonstrates how to build Vite + React microfrontends with Single SPA.
Using this example, you can learn how to set up a microfrontend using single-spa with Module Federation on Vercel. This example demonstrates how to create a microfrontend architecture that allows you to load multiple applications in a single page, enabling independent deployments and development.
The example is available on GitHub at vercel-labs/microfrontends-single-spa-module-federation.
This example demonstrates real-world microfrontend patterns and best practices:
This example implements a hybrid architecture combining single-spa for application orchestration with Module Federation for runtime code sharing:
Root Application (apps/root/
)
Content Application (apps/content/
)
Navigation Application (apps/navigation/
)
Shared Packages (packages/
)
This hybrid approach provides:
To run the example, you will need the following prerequisites:
It is also recommended to have:
Follow these steps to set up the example on your local machine. Make sure you have the prerequisites installed before proceeding.
Clone the repository:
git clone https://github.com/vercel-labs/microfrontends-single-spa-module-federation.gitcd microfrontends-single-spa-module-federation
Install dependencies:
pnpm install
Start the development environment:
pnpm dev
This command starts all applications simultaneously:
Access the application:
Open http://localhost:3024 in your browser to see the federated application where components from different microfrontends are composed together using single-spa and Module Federation.
This example uses the following technologies:
The microfrontends are configured using the microfrontends.json
file. This file defines the applications and their routing. The example uses the following configuration:
// apps/root/microfrontends.json{"$schema": "https://openapi.vercel.sh/microfrontends.json","applications": {"microfrontends-single-spa-module-federation-root": {"development": {"fallback": "microfrontends-single-spa-module-federation-root.vercel.app",},},"microfrontends-single-spa-module-federation-content": {"routing": [{"paths": ["/_content/:path*"],},],},"microfrontends-single-spa-module-federation-navigation": {"routing": [{"paths": ["/_navigation/:path*"],},],},},}
This configuration is defined in the root application, which is the default application of the microfrontends group. The microfrontends.json
file specifies the applications and their routing paths. The development.fallback
field is used to specify a fallback URL. See more details on how to manage your microfrontends in the Managing Microfrontends documentation.
The microfrontends.json
in this example defines three applications:
microfrontends-single-spa-module-federation-root
: The root application that serves as the entry point for the microfrontend architecture. This is the default application of the Microfrontends group.microfrontends-single-spa-module-federation-content
: A microfrontend application that handles content-related functionality. It is routed to paths starting with /_content/
. The application will provide the landing page content for our example.microfrontends-single-spa-module-federation-navigation
: A microfrontend application that handles navigation functionality. It is routed to paths starting with /_navigation/
. The application will provide the navigation components.As we don't specify a specific local Microfrontends proxy port, the local Microfrontends proxy will run on port 3024
by default. You can change this by setting localProxyPort
in the microfrontends.json
file.
To make Microfrontends and Module Federation work, we need to configure Vite in each microfrontend application.
For the navigation
and content
applications providing the Module Federation remotes for the root application, we need to set up the Vite configuration as follows:
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends({basePath: '/_navigation',}) as Plugin,react(),federation({name: 'navigation',manifest: true,filename: 'remoteEntry.js',exposes: {'./header': './src/header/index.tsx','./footer': './src/footer/index.tsx',},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
The only difference between the navigation
and content
applications is the basePath
in the microfrontends
plugin configuration, the name of the Module Federation remote and the exposed modules. The basePath
is set to /_navigation
for the navigation
application and to /_content
for the content
application.
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends({basePath: '/_content',}) as Plugin,react(),federation({name: 'content',manifest: true,filename: 'remoteEntry.js',exposes: {'./landing': './src/landing.tsx',},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
Both configurations use the @module-federation/vite
plugin to set up Module Federation and the @vercel/microfrontends/experimental/vite
plugin to enable microfrontends support. The federation
plugin is used to expose the components of the microfrontend applications, while the microfrontends
plugin is used to configure the base path for the microfrontend routing.
For both the navigation
and content
applications, we expose the components that will be used by the root application. The navigation
application exposes a header and footer component, while the content
application exposes a landing component.
React and React DOM are shared as singletons to ensure that the same instance is used across the microfrontends. This is important for maintaining a consistent state and avoiding issues with multiple instances of React.
The additional specification for a build.target
is set to chrome89
to ensure compatibility with the features used in the microfrontends. In this case we need top-level await support, which is available in Chrome 89 and later.
For the root application, we need to set up the Vite configuration to load the microfrontends and use the exposed components from the navigation
and content
applications:
import { defineConfig, type Plugin } from 'vite';import { federation } from '@module-federation/vite';import tailwindcss from '@tailwindcss/vite';import { microfrontends } from '@vercel/microfrontends/experimental/vite';import { vercelToolbar } from '@vercel/toolbar/plugins/vite';import react from '@vitejs/plugin-react';export default defineConfig({plugins: [tailwindcss(),microfrontends() as Plugin,vercelToolbar(),react(),federation({name: 'root',manifest: true,remotes: {navigation: {type: 'module',name: 'navigation',entry: '/_navigation/remoteEntry.js',},content: {type: 'module',name: 'content',entry: '/_content/remoteEntry.js',},},shared: {react: {singleton: true,},'react/': {singleton: true,},'react-dom': {singleton: true,},'react-dom/': {singleton: true,},},}) as Plugin[],],build: {target: 'chrome89',},});
The root application doesn't expose any components, but it loads the navigation
and content
applications as remotes using Module Federation. The remotes
configuration specifies the entry points for the remote applications, which are the remoteEntry.js
files exposed by the navigation
and content
applications.
As we are using Vite for the navigation
and content
applications providing the Module Federation remotes, we use remotes specified with type: 'module'
to load the remote applications. This allows us to use the native ES module loading capabilities of the browser, which is supported by Vite.
The entry paths for the remotes are set to /_navigation/remoteEntry.js
and /_content/remoteEntry.js
, which correspond to the base paths defined in the microfrontends.json
file. As we are using Vercel Microfrontends solution and in this example we are using client-side rendering, we can use relative URLs for the remotes. This allows the root application to dynamically load the components from the navigation
and content
applications at runtime. The routing will be managed by Vercel Microfrontends, which will ensure that the correct application is loaded based on the path.
The root application is the entry point for the microfrontend architecture. It is responsible for loading the navigation
and content
remotes and rendering their components as single-spa applications.
To create a layout for the root application using single-spa, we can use the following HTML structure:
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Company Landing Page</title><link rel="stylesheet" href="./src/globals.css" /><script type="module" src="./src/index.ts"></script></head><body className="flex min-h-screen flex-col"><div id="single-spa-application:header"></div><div id="single-spa-application:content"></div><div id="single-spa-application:footer"></div></body></html>
To register each application with single-spa, we can use the following code in the src/index.ts
file of the root application:
import { mountVercelToolbar } from '@vercel/toolbar/vite';import { registerApplication, start } from 'single-spa';import './globals.css';registerApplication('header',() => import('navigation/header'),() => true,);registerApplication('footer',() => import('navigation/footer'),() => true,);registerApplication('content',() => import('content/landing'),() => true,);start();mountVercelToolbar();
We register each single-spa application using the registerApplication
function. Each application is registered with a name, a loading function that imports the remote component using dynamic ES module import, and an activity function that determines when the application should be active based on the current route, which will be always true in the case of this example.
In the remote applications, we are using single-spa-react
to create a React component that will be rendered by single-spa. The content
application provides the main page content, while the navigation
application provides the header and footer components.
We need to define the bootstrap
, mount
, and unmount
functions for each component. These functions are used by single-spa to manage the lifecycle of the applications.
import React from 'react';import ReactDOMClient from 'react-dom/client';import singleSpaReact from 'single-spa-react';import './globals.css';function Landing(): React.JSX.Element {return <>{/* ... */}</>;}export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Landing,errorBoundary() {return <></>;},});
For the navigation
application, we define the header and footer components similarly.
// ...export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Header,errorBoundary() {return <></>;},});
// ...export const { bootstrap, mount, unmount } = singleSpaReact({React,ReactDOMClient,rootComponent: Footer,errorBoundary() {return <></>;},});
The difference being which rootComponent
is used for each application. The Landing
component in the content
application, and the Header
and Footer
components in the navigation
application.
With everything needed set up, you can now run the microfrontend applications locally. The root application will be available at http://localhost:3024
, and it will load the content
and navigation
applications as microfrontends.
To start a development server for each application, we use a dev
npm script in each application's package.json
file. The dev
script uses Vite to start the development server for the application and also specifies the port to run on when using the Microfrontends proxy.
// apps/root/package.json{"scripts": {"build": "vite build","dev": "vite --port $(microfrontends port)","start": "vite preview --port $(microfrontends port)",},}
Run the following command in the root directory of the cloned repository to start the development server and the Microfrontends proxy:
pnpm dev
This command will start all the applications in the monorepo and also starts the Microfrontends proxy on port 3024
.
Deploy each microfrontend independently to experience the full power of distributed development:
Each microfrontend can be deployed independently, enabling:
Fork the repository: Create your own copy of the repository on GitHub.
Set up Vercel projects: Create separate Vercel projects for each microfrontend:
root
, content
, navigation
)apps/root
, apps/content
, apps/navigation
)Configure Microfrontends group:
Environment configuration:
microfrontends.json
file is properly configuredDeploy and verify:
Each application includes optimized Vercel configuration:
Once deployed, your applications will be accessible at URLs similar to:
https://your-root-app.vercel.app
https://your-content-app.vercel.app
https://your-navigation-app.vercel.app
The root application will automatically load the content and navigation microfrontends based on the routing configuration in microfrontends.json
.
The example is deployed to Vercel at https://vercel-microfrontends-single-spa.vercel.app already for you to check out.
You can develop microfrontends in isolation:
# Work on the root application onlycd apps/rootpnpm dev# Work on the content application onlycd apps/contentpnpm dev# Work on the navigation application onlycd apps/navigationpnpm dev
# Build all applicationspnpm build# Run linting across all appspnpm lint# Type check all applicationspnpm typecheck# Run all quality checkspnpm checks
vite.config.ts
:
exposes: {'./newComponent': './src/path/to/component.tsx'}
global.d.ts
:
declare module 'remoteName/newComponent' {const Component: React.ComponentType;export default Component;}
import NewComponent from 'remoteName/newComponent';
Module Federation loading errors:
# Ensure all applications are runningpnpm dev
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 issuespnpm typecheck# Verify all federated modules are built correctlypnpm build
This example combines both single-spa and Module Federation for optimal microfrontend architecture:
Feature | single-spa | Module Federation | Combined Approach |
---|---|---|---|
Component Sharing | URL-based routing | Runtime code sharing | Both runtime sharing and routing |
Bundle Size | Independent bundles | Shared dependencies | Optimized shared dependencies |
Integration | Application-level | Component-level | Multi-level integration |
Lifecycle Management | Built-in lifecycle | Manual lifecycle | single-spa manages MF components |
Use Case | App orchestration | Code sharing | Complete microfrontend solution |
Benefits of the combined approach:
The Vercel Toolbar is included in the root application to provide insights and debugging capabilities for the microfrontend applications. The toolbar can be mounted using the mountVercelToolbar
function from the @vercel/toolbar/vite
package.
Learn more about the Vercel Toolbar in the Vercel Toolbar documentation.
This example demonstrates how to set up a microfrontend architecture using single-spa with Module Federation on Vercel. By following the steps outlined in this guide and the provided repo on GitHub, you can create a scalable and maintainable microfrontend application that allows for independent deployments and development.