Setting Up Vite with Federation Plugins #

A comprehensive architectural walkthrough for implementing Module Federation in Vite ecosystems. This guide details plugin initialization, host/remote manifest configuration, runtime dependency resolution, and production build strategies for enterprise micro-frontends. Understanding the shift from Webpack’s runtime to Vite’s native ESM-based federation model is critical for teams adopting Webpack & Vite Module Federation Implementation architectural standards.

Key Implementation Objectives:


Plugin Installation & Base Configuration #

Initialize the Vite project with federation capabilities and define core host/remote manifests using TypeScript-safe configuration. Begin by installing the official plugin and registering it in vite.config.ts. Define expose mappings for local components and remotes for external entry points. Configure shared blocks with explicit version pinning to prevent runtime collisions. For teams transitioning legacy setups, reference Migrating from Webpack to Vite for faster federation builds to align CI/CD pipeline adjustments with Vite’s native ESM resolution.

// vite.config.ts
import { defineConfig } from 'vite';
import federation from '@originjs/vite-plugin-federation';

export default defineConfig({
 plugins: [
 federation({
 name: 'host_app',
 remotes: {
 remote_ui: 'http://localhost:5001/assets/remoteEntry.js'
 },
 shared: {
 react: { singleton: true, requiredVersion: '^18.2.0' },
 'react-dom': { singleton: true, requiredVersion: '^18.2.0' }
 }
 })
 ]
});

Runtime vs Build-Time Implications:


Remote Module Consumption & Dynamic Imports #

Wire host applications to consume exposed remote components and handle async loading patterns without blocking the main thread. Implement import('remote_app/Component') syntax alongside framework-specific lazy loading utilities like React.lazy() or Vue’s defineAsyncComponent. Configure fallback UI states and error boundaries for failed remote resolutions. Unlike traditional setups, Vite’s static analysis approach contrasts sharply with Configuring Webpack Module Federation, enabling faster dev server cold starts and eliminating the need for complex runtime container bootstrapping scripts.

// FederatedView.tsx
import { lazy, Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';

const RemoteDashboard = lazy(() => import('remote_ui/Dashboard'));

export function FederatedView() {
 return (
 <ErrorBoundary fallback={<div>Module failed to load</div>}>
 <Suspense fallback={<div>Loading remote module...</div>}>
 <RemoteDashboard />
 </Suspense>
 </ErrorBoundary>
 );
}

Runtime vs Build-Time Implications:


Runtime Dependency Sharing & Version Conflicts #

Resolve singleton dependency collisions, manage cross-app state synchronization, and prevent duplicate framework bundling. Enforce singleton: true and strictVersion: true in the shared configuration for UI frameworks or state management libraries. Implement fallback version negotiation when remote apps request incompatible dependency ranges. Apply enterprise-scale resolution patterns from Managing Shared Dependencies at Runtime to isolate state boundaries and prevent memory leaks. For advanced manifest rewriting and hook overrides, extend plugin behavior using Using Vite plugin architecture for custom federation.

// shared.config.ts
export const sharedConfig = {
 shared: {
 '@tanstack/react-query': {
 singleton: true,
 requiredVersion: '^4.0.0',
 strictVersion: true,
 eager: true
 },
 'lodash-es': {
 singleton: false,
 requiredVersion: '^4.17.21',
 strictVersion: false
 }
 }
};

Runtime vs Build-Time Implications:


Cross-Origin Validation & Local Development Workflows #

Verify module resolution, enforce CORS compliance, and maintain Hot Module Replacement (HMR) across federated boundaries. Configure server.cors and server.origin to allow remote manifest injection during vite dev. Validate remote entry point availability using network inspector and vite preview staging. Debug HMR desync by isolating shared dependency updates and forcing full reloads on manifest changes. Implement automated smoke tests to verify remote chunk integrity before merging PRs, ensuring that federated contracts remain stable across independent deployment cycles.

Development Checklist:

  1. Set server.cors: true and server.origin: 'http://localhost:5173' in the host config.
  2. Run remote apps on distinct ports (5001, 5002, etc.) and verify remoteEntry.js is accessible via browser.
  3. Use vite preview to simulate production asset routing and validate chunk hashes.
  4. Monitor WebSocket connections for HMR payloads; if remote updates fail to propagate, implement a lightweight polling script to trigger window.location.reload().

Production Build Optimization & Asset Routing #

Finalize build outputs, optimize chunk splitting, and configure CDN/static hosting for federated assets. Adjust build.rollupOptions.output to enforce stable chunk hashing and prevent cache invalidation storms. Implement Optimizing chunk splitting for remote apps to reduce initial payload size and defer non-critical remote code. Configure static asset base paths and CDN rewrite rules to ensure remote manifests resolve correctly in production. Validate final bundle sizes using rollup-plugin-visualizer and enforce budget thresholds in CI pipelines.

Production Configuration Strategy:


Common Pitfalls #

Issue Root Cause & Resolution
HMR desynchronization across federated boundaries Vite’s native HMR does not automatically propagate to remote modules. Developers must implement manual manifest polling or configure server.hmr.overlay to trigger full reloads when remote entry points update.
Singleton dependency version mismatch at runtime When host and remote apps specify incompatible requiredVersion ranges, the plugin throws a runtime error. Strict version checking must be paired with explicit peer dependency alignment in package.json.
CORS blocking remote manifest injection in production Static hosting environments often block cross-origin script execution. Missing Access-Control-Allow-Origin headers on remote asset servers will prevent the host from fetching remoteEntry.js.

FAQ #

Can Vite Module Federation work with non-ESM legacy dependencies? Yes, but legacy CommonJS modules require explicit transformation via @rollup/plugin-commonjs or must be wrapped in ESM-compatible entry points before federation exposure. The plugin expects ES module syntax for static analysis and dynamic import resolution.

How do I handle remote module versioning without breaking the host? Implement semantic version ranges in the shared config, enforce strictVersion: true for critical frameworks, and use dynamic import fallbacks to load alternative remote versions when negotiation fails. Version negotiation occurs at runtime; mismatched ranges trigger graceful degradation rather than hard crashes if fallbacks are configured.

Does Vite’s dev server support live reloading for remote apps? Vite supports per-app HMR, but federated remotes require manual coordination. Configure server.proxy to route remote requests and implement a lightweight WebSocket listener to trigger host reloads on remote manifest updates. This ensures the host reflects remote component changes without full page refreshes during local development.