# Micro Frontends

> When to activate: micro frontends, module federation, single-spa, independent deployment, MFE, runtime integration, microfrontend

- Skill: `mattakushi432/micro-frontends` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattakushi432/micro-frontends`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattakushi432/micro-frontends/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: Mattakushi432 (https://skillmd.com/u/mattakushi432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mattakushi432/micro-frontends

---

# Micro-Frontend Patterns

## When to Use MFEs

Use when: independent teams, independent deployments, different tech stacks, large-scale apps.
Avoid when: small team, shared release cycle, high communication overhead not justified.

## Module Federation (Webpack 5)

```js
// host/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  plugins: [new ModuleFederationPlugin({
    name: 'host',
    remotes: {
      auth:      'auth@http://localhost:3001/remoteEntry.js',
      dashboard: 'dashboard@http://localhost:3002/remoteEntry.js',
    },
    shared: {
      react: { singleton: true, requiredVersion: '^18' },
      'react-dom': { singleton: true, requiredVersion: '^18' },
    },
  })]
};

// host/src/App.jsx
const LoginForm = React.lazy(() => import('auth/LoginForm'));
const Dashboard = React.lazy(() => import('dashboard/Dashboard'));
```

```js
// auth/webpack.config.js — Remote
module.exports = {
  plugins: [new ModuleFederationPlugin({
    name: 'auth',
    filename: 'remoteEntry.js',
    exposes: {
      './LoginForm': './src/components/LoginForm',
      './AuthProvider': './src/providers/AuthProvider',
    },
    shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
  })]
};
```

## Vite Module Federation

```ts
// vite.config.ts
import federation from '@originjs/vite-plugin-federation';

// Host
export default defineConfig({
  plugins: [federation({
    remotes: { mfe_nav: 'http://localhost:3001/assets/remoteEntry.js' },
    shared: ['react', 'react-dom'],
  })]
});

// Remote (must build with target: 'esnext')
export default defineConfig({
  plugins: [federation({
    name: 'mfe_nav',
    filename: 'remoteEntry.js',
    exposes: { './NavBar': './src/NavBar' },
    shared: ['react', 'react-dom'],
  })],
  build: { target: 'esnext', minify: false }
});
```

## Single-SPA

```js
// root-config.js
import { registerApplication, start } from 'single-spa';

registerApplication({
  name: '@myorg/navbar',
  app: () => System.import('@myorg/navbar'),
  activeWhen: () => true,
});

registerApplication({
  name: '@myorg/dashboard',
  app: () => System.import('@myorg/dashboard'),
  activeWhen: ['/dashboard'],
});

start({ urlRerouteOnly: true });
```

## Web Component Integration

```js
// Any framework exports a web component
// React MFE exposes as custom element
import { createRoot } from 'react-dom/client';
import { Dashboard } from './Dashboard';

class DashboardElement extends HTMLElement {
  #root;
  connectedCallback() {
    this.#root = createRoot(this);
    this.#root.render(<Dashboard config={this.#getConfig()} />);
  }
  disconnectedCallback() { this.#root.unmount(); }
  #getConfig() {
    return { theme: this.getAttribute('theme') ?? 'light' };
  }
}
customElements.define('mfe-dashboard', DashboardElement);

// Host (any framework) uses it:
// <mfe-dashboard theme="dark"></mfe-dashboard>
```

## Cross-MFE Communication

```js
// Use a shared event bus (CustomEvents on window)
// auth MFE emits:
window.dispatchEvent(new CustomEvent('mfe:auth:login', {
  detail: { userId: '123', token: 'abc' }
}));

// dashboard MFE listens:
window.addEventListener('mfe:auth:login', ({ detail }) => {
  store.setUser(detail);
});

// Or use a shared store via singleton
// shared-store/index.js (exposed via module federation)
import { create } from 'zustand';
export const useSharedStore = create(set => ({
  user: null, setUser: user => set({ user }),
}));
```

## Deployment Pattern

```
CDN / Nginx (host)
├── /                → host app (index.html + hashed JS)
├── /auth/           → auth MFE (remoteEntry.js + chunks)
└── /dashboard/      → dashboard MFE (remoteEntry.js + chunks)

# Each MFE deployed independently via own CI/CD pipeline
# remoteEntry.js is the only stable URL — all other files are hashed
```

## Shared Design System

```js
// design-system remote
exposes: {
  './Button': './src/Button',
  './tokens': './src/tokens',
  './theme': './src/ThemeProvider',
}
// All MFEs import from design-system remote
// Single source of truth for UI components
```

