Micro-frontends
Modular architecture decomposing frontend applications into autonomous teams developing independently deployable features.
Updated on January 26, 2026
Micro-frontends apply microservices principles to frontend architecture, decomposing monolithic applications into smaller, autonomous fragments. This approach enables multiple teams to work independently on different parts of a web application, each with its own tech stack, deployment cycle, and governance. The primary goal is to improve both organizational and technical scalability of complex frontend applications.
Architectural Fundamentals
- Team autonomy: each micro-frontend is developed, tested, and deployed independently by a dedicated team
- Technical decoupling: ability to use different frameworks (React, Vue, Angular) within the same application
- Runtime composition: integration of fragments via techniques like module federation, Web Components, or iframe sandboxing
- Code isolation: each micro-frontend has its own dependencies without conflicts with other modules
Strategic Benefits
- Organizational scalability: multiple teams can work in parallel without blocking dependencies
- Independent deployments: reduced risk by deploying only modified parts of the application
- Technology freedom: ability to progressively modernize the application without complete migration
- Enhanced resilience: failure of one micro-frontend doesn't necessarily affect the entire application
- Optimized time-to-market: reduced development cycles through autonomous teams and smaller scopes
Practical Architecture Example
Consider an e-commerce platform where each major section becomes an independent micro-frontend:
// Container application (host)
import { loadRemoteModule } from '@module-federation/runtime';
// Micro-frontends configuration
const microFrontends = {
catalog: {
url: 'https://catalog.ecommerce.com/remoteEntry.js',
scope: 'catalog',
module: './ProductList'
},
cart: {
url: 'https://cart.ecommerce.com/remoteEntry.js',
scope: 'cart',
module: './ShoppingCart'
},
checkout: {
url: 'https://checkout.ecommerce.com/remoteEntry.js',
scope: 'checkout',
module: './CheckoutFlow'
}
};
// Dynamic loading of a micro-frontend
async function loadMicroFrontend(name: string) {
const config = microFrontends[name];
try {
const module = await loadRemoteModule({
remoteEntry: config.url,
remoteName: config.scope,
exposedModule: config.module
});
return module.default;
} catch (error) {
console.error(`Failed to load ${name}:`, error);
return FallbackComponent; // Fallback component
}
}
// Routing with lazy loading
const routes = [
{
path: '/products',
component: () => loadMicroFrontend('catalog')
},
{
path: '/cart',
component: () => loadMicroFrontend('cart')
},
{
path: '/checkout',
component: () => loadMicroFrontend('checkout')
}
];// Webpack Module Federation configuration
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'catalog',
filename: 'remoteEntry.js',
exposes: {
'./ProductList': './src/components/ProductList',
'./ProductDetail': './src/components/ProductDetail'
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
// Share common dependencies to optimize bundle size
'shared-ui-library': { singleton: true }
}
})
]
};Practical Implementation
- Define boundaries: identify coherent business domains and decompose them into autonomous micro-frontends
- Choose integration strategy: Module Federation, Web Components, iframes, or server-side composition (SSR)
- Establish a design system: create a shared component library to ensure visual consistency
- Implement inter-module communication: use an event bus, shared state management, or Custom Events
- Configure CI/CD: set up independent deployment pipelines for each micro-frontend
- Manage versioning: establish clear API contracts between modules and use semantic versioning
- Monitor performance: track loading times and the impact of each micro-frontend on Web Vitals
Architecture Tip
Start small: don't adopt micro-frontends for a simple application. This architecture brings the most value for teams of 50+ developers or applications with clearly distinct business domains. To begin, experiment with 2-3 micro-frontends before extending the approach across the entire organization.
Associated Tools and Frameworks
- Webpack Module Federation: native solution for sharing code between JavaScript applications
- Single-SPA: framework for orchestrating multiple frontend applications within the same container
- Bit: platform for building, versioning, and composing independent components
- Nx: monorepo build tool with native support for micro-frontends and module federation
- Piral: framework for creating modular portals with micro-frontends based on pilets
- SystemJS: dynamic module loader for runtime integration of micro-frontends
Micro-frontends represent a major evolution in enterprise web application architecture, enabling the shift from teams organized by technical skills to cross-functional teams aligned with business value. While this approach introduces additional operational complexity, it offers unprecedented organizational scalability and significantly reduces coupling between teams. For large organizations with complex applications, micro-frontends constitute a strategic lever to accelerate delivery and maintain long-term velocity.
