This is an end-to-end micro frontend example using React, Vite, and Module Federation.
shellapp handles routing and shared state.productsremote exposes the product catalog UI.cartremote exposes the cart UI.@mfe/contractskeeps TypeScript contracts shared and stable.
- Host/Shell:
apps/shell(port5173) - Remote 1:
apps/products(port5174) - Remote 2:
apps/cart(port5175)
Runtime flow:
- User opens shell (
http://127.0.0.1:5173). - Shell lazy-loads
products/ProductsPageandcart/MiniCartfrom remote entry files. - Products remote emits user intent via callback (
onAddToCart). - Shell owns and updates cart state.
- Shell passes state into Cart remote via props.
- Independent deployable frontends with isolated responsibilities.
- Strong contracts (
@mfe/contracts) to prevent drift between teams/apps. React.lazy+Suspenseto keep load behavior explicit.- Error boundaries around every remote to isolate failures.
- Strict TypeScript config and semantic, accessible HTML structure.
- Shared dependency version constraints in federation config to reduce runtime mismatch risk.
react-microfrontend-example/
apps/
shell/
products/
cart/
packages/
contracts/
- Node.js 20+
- Yarn 1.22+
- Install dependencies:
yarn install- Start remotes first (in separate terminals):
yarn dev:products
yarn dev:cartThese scripts run vite build --watch + vite preview for remotes. With @originjs/vite-plugin-federation, this is the reliable way to expose remoteEntry.js during local development.
- Start shell:
yarn dev:shell- Open
http://127.0.0.1:5173.
Alternative one-command startup:
yarn dev:allyarn buildShell uses these environment variables if provided:
VITE_PRODUCTS_REMOTE_URL(defaulthttp://127.0.0.1:5174/assets/remoteEntry.js)VITE_CART_REMOTE_URL(defaulthttp://127.0.0.1:5175/assets/remoteEntry.js)
Example:
VITE_PRODUCTS_REMOTE_URL=https://products.example.com/assets/remoteEntry.js \
VITE_CART_REMOTE_URL=https://cart.example.com/assets/remoteEntry.js \
yarn dev:shell- Put all apps behind HTTPS.
- Configure CSP and security headers in your edge/proxy.
- Version remote contracts and avoid breaking changes.
- Add independent CI for each remote and contract tests in shell.
- Use observability (error tracking + metrics) for each remote and shell.