Complete micro frontend e-commerce application built with Next.js, Module Federation, and modern web technologies
Live Demo: π·οΈ Spider-Man Store (Micro Frontend in Action)
Individual Micro Frontends:
- Products Service: Products Catalog
- Cart Service: Shopping Cart
- Host Application: Complete Store
- Browse Products: View Spider-Man themed items with pricing
- Add to Cart: Click any product to add it to your cart
- Real-time Updates: Cart updates instantly across all micro frontends
- Checkout: Complete the purchase flow with notifications
- Demo & Live Preview
- Overview
- Architecture
- Micro Frontend Communication
- Features
- Performance
- Getting Started
- Project Structure
- Technologies
- Testing
- Development Guidelines
- Deployment
- Contributing
This project demonstrates a production-ready micro frontend architecture using Next.js and Module Federation. It features a Spider-Man themed e-commerce store with three independent applications working together seamlessly.
The architecture showcases modern patterns for building scalable, maintainable, and independently deployable frontend applications.
graph TB
subgraph "Host Application (Port 3000)"
H[Host App]
H --> HC[Cart Context]
H --> HA[Analytics]
H --> HL[Layout & Routing]
end
subgraph "Remote Products (Port 3001)"
P[Products App]
P --> PL[Product List]
P --> PC[Product Cards]
end
subgraph "Remote Cart (Port 3002)"
C[Cart App]
C --> CC[Cart Component]
C --> CB[Cart Buttons]
end
H -.->|Module Federation| P
H -.->|Module Federation| C
P -.->|Global Context| HC
C -.->|Global Context| HC
| Application | Port | Responsibility | Exposes |
|---|---|---|---|
| Host | 3000 | Main orchestrator, layout, state management | CartProvider, Analytics |
| Products | 3001 | Product catalog and related components | ProductList, ProductCard |
| Cart | 3002 | Shopping cart functionality | Cart, CartButton |
How it works:
// Host exposes cart context globally
window.__CART_CONTEXT__ = {
addToCart: (product) => { /* ... */ },
items: [],
updateQuantity: (id, quantity) => { /* ... */ },
removeItem: (id) => { /* ... */ }
}
// Remote apps access the global context
if (window.__CART_CONTEXT__) {
window.__CART_CONTEXT__.addToCart(product);
}Why this approach?
- β Simplicity: Easy to implement and understand
- β Framework Agnostic: Works with any JavaScript framework
- β Real-time Sync: Immediate state updates across micro frontends
- β No Additional Dependencies: No need for message buses or event systems
- β Type Safety: Can be typed with TypeScript declarations
Trade-offs:
β οΈ Global State: Uses global namespace (mitigated with namespacing)β οΈ Polling: Uses setInterval for updates (could use observers)
// Publish events
window.dispatchEvent(new CustomEvent('cart:add', {
detail: { product }
}));
// Subscribe to events
window.addEventListener('cart:add', (event) => {
// Handle cart addition
});Pros: Decoupled, event-driven, no polling
Cons: More complex, harder to debug, no type safety
// Shared store across micro frontends
import { useCartStore } from '@shared/cart-store';
const addToCart = useCartStore(state => state.addToCart);Pros: Structured state management, devtools support
Cons: Shared dependency, version conflicts, bundle duplication
// Host passes handlers as props
<ProductList onAddToCart={handleAddToCart} />Pros: Explicit data flow, React-like patterns
Cons: Props coupling, harder to maintain with deep nesting
// Cross-frame communication
parent.postMessage({ type: 'ADD_TO_CART', product }, '*');Pros: True isolation, works with iframes
Cons: Complex serialization, performance overhead
- Rapid Prototyping: Fastest to implement and iterate
- Type Safety: Easy to add TypeScript definitions
- React Compatibility: Works well with React's mental model
- Performance: Direct function calls, no serialization
- Debugging: Easy to inspect state in browser devtools
For production applications, consider migrating to Custom Events or a Shared State Library for better architecture.
- Product catalog with Spider-Man themed items
- Shopping cart with real-time updates
- Add/remove items with quantity management
- Checkout flow with notifications
- Pricing in Brazilian Reais (R$)
- Module Federation: Runtime code sharing between applications
- HTTP Client: Robust client with exponential backoff retry, jitter, and idempotency
- OpenTelemetry: Distributed tracing and observability with RED/USE metrics
- Analytics: Page view and interaction tracking
- Responsive Design: Mobile-first approach with modern CSS
- Error Handling: Graceful degradation and error boundaries
- Unit Tests: Jest + Testing Library for component testing
- E2E Tests: Playwright for integration testing
- TypeScript: Full type safety across all applications
- Linting: ESLint with consistent code standards
- Host App: ~180KB (gzipped)
- Products Remote: ~95KB (gzipped)
- Cart Remote: ~85KB (gzipped)
- Shared Packages: ~45KB (gzipped)
- Total Bundle: ~405KB (competitive for micro frontend architecture)
- First Contentful Paint: < 1.2s
- Time to Interactive: < 2.5s
- Lighthouse Score: 95+ (Performance)
- Module Federation Load Time: < 300ms per remote
- Code Splitting: Automatic route-based splitting
- Lazy Loading: Dynamic imports for remote components
- Bundle Sharing: React/ReactDOM shared as singletons
- HTTP Caching: Aggressive caching for static assets
- Image Optimization: Next.js Image component with WebP support
- Node.js 18+ (LTS recommended)
- PNPM 8+ (for efficient package management)
- Clone the repository:
git clone https://github.com/Felipeness/micro-frontend-nextjs.git
cd micro-frontend-nextjs- Install dependencies:
pnpm install- Start all applications:
pnpm run dev- Open your browser:
- Main Store: http://localhost:3000
- Products Service: http://localhost:3001
- Cart Service: http://localhost:3002
# Install dependencies
pnpm install
# Start all apps in development mode
pnpm run dev
# Run tests
pnpm test
# Run E2E tests
pnpm test:e2e
# Build all applications
pnpm run build
# Type checking
pnpm run type-check
# Linting
pnpm run lintmicro-frontend-nextjs/
βββ π± apps/
β βββ host/ # Main application (Port 3000)
β β βββ src/
β β β βββ components/ # Shared UI components
β β β βββ context/ # React Context providers
β β β βββ lib/ # Utility functions
β β β βββ types/ # TypeScript definitions
β β βββ pages/ # Next.js pages
β β βββ styles/ # Global styles
β β βββ next.config.js # Module Federation config
β β
β βββ remote-products/ # Products micro frontend (Port 3001)
β β βββ src/components/ # Product-related components
β β βββ pages/ # Product pages
β β βββ next.config.js # MF config for products
β β
β βββ remote-cart/ # Cart micro frontend (Port 3002)
β βββ src/components/ # Cart-related components
β βββ pages/ # Cart pages
β βββ next.config.js # MF config for cart
β
βββ π¦ packages/
β βββ http-client/ # Shared HTTP client with retry logic
β β βββ src/
β β β βββ http-client.ts # Main HTTP client
β β β βββ retry.ts # Retry mechanisms
β β β βββ types.ts # TypeScript definitions
β β βββ __tests__/ # Unit tests
β β
β βββ telemetry/ # OpenTelemetry configuration
β βββ src/
β β βββ telemetry.ts # Tracing setup
β β βββ types.ts # Telemetry types
β βββ __tests__/ # Tests
β
βββ π§ types/ # Global TypeScript definitions
βββ π package.json # Root package configuration
βββ π pnpm-workspace.yaml # PNPM workspace config
βββ π README.md # This file
- Next.js 14 - React framework with App Router
- React 18 - UI library with concurrent features
- TypeScript 5 - Type-safe JavaScript
- Module Federation - Webpack 5 micro frontend solution
- @module-federation/nextjs-mf - Next.js Module Federation plugin
- React Context - Local state management
- Global Context Pattern - Cross-micro frontend communication
- Custom Analytics - Event tracking and user interaction monitoring
- Custom HTTP Client - With exponential backoff and jitter
- OpenTelemetry - Distributed tracing and metrics
- RED/USE Metrics - Request rate, error rate, duration monitoring
- Jest - Unit testing framework
- Testing Library - React component testing
- Playwright - End-to-end testing
- ESLint - Code linting and standards
- PNPM - Fast, disk space efficient package manager
- Concurrently - Run multiple commands simultaneously
- TypeScript Project References - Monorepo type checking
| Package/App | Statements | Branches | Functions | Lines | Status |
|---|---|---|---|---|---|
| host | 96.36% | 87.5% | 84.61% | 98.03% | β Excellent |
| http-client | 93.28% | 96.96% | 80% | 96.09% | β Excellent |
| remote-products | 78.57% | 85.71% | 84.61% | 78.57% | β Good |
| remote-cart | 53.44% | 44.82% | 57.89% | 51.78% |
- β Analytics Library - Complete tracking and session management
- β Metrics Library - RED metrics and performance monitoring
- β Retry Utilities - Exponential backoff and jitter implementation
- β TelemetryProvider - OpenTelemetry integration
- β CartContext - Shopping cart state management
- β ProductCard - Product display component
- β ProductList - Product catalog component
# Run all unit tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage
# Test specific package
pnpm --filter http-client test# Run Cypress tests headlessly
pnpm cypress run
# Open Cypress Test Runner
pnpm cypress open
# Run specific test file
pnpm cypress run --spec "cypress/e2e/spider-man-store.cy.ts"# Run Playwright E2E tests
pnpm test:e2e
# Run E2E tests in UI mode
pnpm test:e2e:ui
# Run E2E tests for specific browser
pnpm test:e2e --project=chromium- Unit Tests: Located in
__tests__folders within each package - Integration Tests: Located in
e2efolders within applications - Cypress Tests: Located in
cypress/e2efolder - Test Utilities: Shared test helpers and mocks
- Total Tests: 144+ unit tests
- E2E Tests: 15 Cypress scenarios
- Coverage Goal: 85% minimum for critical paths
- Test Execution Time: ~3 seconds for all unit tests
- Conventional Commits: Use semantic commit messages
- TypeScript Strict Mode: All code must pass strict type checking
- ESLint Rules: Follow established linting rules
- Component Structure: Keep components small and focused
- Independent Deployments: Each app should be deployable independently
- Shared Dependencies: Minimize shared runtime dependencies
- Error Boundaries: Implement proper error handling
- Performance: Lazy load micro frontends when possible
- Testing: Test each micro frontend in isolation
- Create new app in
apps/directory - Configure Module Federation in
next.config.js - Add to workspace in
pnpm-workspace.yaml - Update host application to consume new remote
- Add appropriate tests and documentation
The easiest way to deploy this micro frontend architecture:
# Install Vercel CLI
npm i -g vercel
# Deploy each application
cd apps/host && vercel --prod
cd apps/remote-products && vercel --prod
cd apps/remote-cart && vercel --prod# Build and run with Docker Compose
docker-compose up --build
# Or build individual containers
docker build -t spider-man-host ./apps/host
docker build -t spider-man-products ./apps/remote-products
docker build -t spider-man-cart ./apps/remote-cartCreate .env.local files in each app with:
# Host App
NEXT_PUBLIC_PRODUCTS_URL=https://your-products-app.vercel.app
NEXT_PUBLIC_CART_URL=https://your-cart-app.vercel.app
NEXT_PRIVATE_LOCAL_WEBPACK=true
# Remote Apps
NEXT_PUBLIC_HOST_URL=https://your-host-app.vercel.app- CDN: Use a CDN for static assets and Module Federation remotes
- CORS: Configure CORS policies for cross-origin module loading
- Error Monitoring: Add Sentry or similar for production error tracking
- Load Balancing: Consider load balancers for high-traffic deployments
We welcome contributions! Here's how to get started:
- Fork the repository
- Clone your fork:
git clone https://github.com/your-username/micro-frontend-nextjs.git - Create a feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
pnpm install - Make your changes following our coding standards
- Test your changes:
pnpm test && pnpm test:e2e - Commit using conventional commits:
git commit -m "feat: add amazing feature" - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
- π Bug Fixes: Issues with existing functionality
- β¨ New Features: Additional micro frontend capabilities
- π Documentation: Improvements to docs and examples
- π§ͺ Tests: Better test coverage and quality
- π Performance: Optimization improvements
- π¨ UI/UX: Better user experience and design
- All submissions require review by project maintainers
- We use automated checks (tests, linting, type checking)
- Feedback is usually provided within 48 hours
- Breaking changes require documentation updates
- π¬ Discussions: Use GitHub Discussions for questions
- π Issues: Use GitHub Issues for bug reports
- π§ Email: Contact maintainers for sensitive matters
This project is open source and available under the MIT License.
- π Documentation: Check this README and inline code comments
- π Issues: Search existing issues before creating new ones
- π‘ Discussions: Use GitHub Discussions for questions and ideas
- π§ Direct Contact: Reach out to @Felipeness
- β Star this repo if you find it helpful
- π΄ Fork to create your own version
- π’ Share with others who might benefit
- π€ Contribute to make it even better
Made with β€οΈ by Felipe Ness - Building the future of micro frontends