Module Federation and Micro-frontends with Vite
Module Federation allows splitting a large application into independent micro-frontends deployed separately, yet still sharing code and dependencies at runtime. Webpack pioneered it; Vite and Rollup now support it through plugins.
What's Involved
Setting up module federation, configuring host and remote modules, shared dependencies, async boundaries, deployment strategy.
Installation
npm install -D @originjs/vite-plugin-federation
Host Configuration
// vite.config.ts for main application
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
react(),
federation({
name: 'host',
remotes: {
dashboard: 'http://localhost:5001/assets/remoteEntry.js',
admin: 'http://localhost:5002/assets/remoteEntry.js',
},
shared: ['react', 'react-dom', 'react-router-dom'],
}),
],
build: {
target: 'esnext',
},
})
Remote Configuration
// vite.config.ts for remote (dashboard)
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
react(),
federation({
name: 'dashboard',
filename: 'remoteEntry.js',
exposes: {
'./Dashboard': './src/Dashboard.tsx',
'./hooks': './src/hooks/index.ts',
},
shared: ['react', 'react-dom', 'react-router-dom'],
}),
],
})
Host Usage
// App.tsx
import { lazy, Suspense } from 'react'
const Dashboard = lazy(() => import('dashboard/Dashboard'))
const Admin = lazy(() => import('admin/AdminPanel'))
export function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/admin" element={<Admin />} />
</Routes>
</Suspense>
)
}
Timeline
Basic micro-frontend setup — 2–3 days. Multiple remotes with shared libraries — 1 week. Production deployment strategy — 2 weeks.







