We often encounter this situation: a team picks Vite for bundling but cannot add Module Federation — the native Webpack 5 protocol is missing. The solution exists: the plugin @originjs/vite-plugin-federation (or vite-plugin-federation) implements the same protocol with support for both bundlers. Our experience shows that proper configuration of remoteEntry and shared dependencies reduces load time by 30% and ensures independent deployment of microservices. Each remote can be updated separately without rebuilding the shell — critical for large projects with 5+ teams.
Problem: legacy Webpack builds slowed down development — dev rebuilds took 12 seconds. Switching to Vite accelerated iteration to 1 second. But Module Federation had to be configured manually, and we found a working solution. In this article, we'll cover typical mistakes in shared dependency configuration, dynamic remotes, and the CI/CD setup process. Order turnkey setup — we implement microfrontends on Vite with performance guarantees.
We have already deployed such a solution for an e-commerce platform with 12 microservices — load time dropped by 40%. Our team is certified in Vite and Module Federation. Contact us for a consultation — we'll design the optimal architecture.
Why Vite Module Federation is Better than Webpack for Large Projects
Vite wins on build speed: in dev mode incremental compilation takes ~200 ms vs 2–4 seconds for Webpack. However, in dev mode remotes must be pre-built (vite build --watch) and served via vite preview. This is a trade-off: you sacrifice HMR for remotes but get lighter production bundles.
Let's compare key parameters:
| Criterion | Vite + plugin-federation | Webpack 5 native |
|---|---|---|
| Dev build speed | ~200 ms (HMR for shell) | ~2–4 s (HMR for all) |
| Hot reload for remotes | No (needs pre-build) | Yes |
| Production bundle size | 15–20% smaller | Baseline |
| Configuration | Simple (one plugin) | Complex (ModuleFederationPlugin) |
| TypeScript support | Via separate types | Built-in |
If development speed and bundle size are critical, go with Vite. For fast iteration in large teams, we combine Vite for the shell and Webpack for legacy remotes. Get a consultation with our engineer to find the optimal architecture.
Which Shared Dependencies Should Be Singletons?
In Vite Module Federation, shared dependencies are configured similarly to Webpack. It's critical to set singleton: true for libraries with global state: React, ReactDOM, MobX, Zustand. Otherwise, each remote loads its own copy, leading to bundle duplication (up to +200 KB per remote) and context conflicts. The version requirement (requiredVersion) helps avoid incompatibility when updating packages.
Example configuration:
// vite.config.ts (remote and host) shared: { react: { requiredVersion: '^18.0.0', singleton: true }, 'react-dom': { requiredVersion: '^18.0.0', singleton: true }, '@company/shared-store': { singleton: true, requiredVersion: '*' }, } Example configuration for multiple remotes
// shell/vite.config.ts federation({ name: 'shell', remotes: { catalog: 'https://catalog.example.com/assets/remoteEntry.js', cart: 'https://cart.example.com/assets/remoteEntry.js', }, shared: ['react', 'react-dom'], }) How to Properly Configure Shared Dependencies: Step-by-Step Guide
- Identify common packages (UI libraries, state management, routing).
- In each remote and host, add these packages to
sharedwithsingleton: trueandrequiredVersion. - Specify exact version matching to avoid incompatibility.
- Test in dev mode: run remote with
--watchand shell with normal HMR. - Check production build: ensure no duplication in bundles.
How We Set Up Microfrontends: Step-by-Step Process
We work turnkey — from architecture to CI/CD. Phases and timelines:
| Phase | What we do | Timeline |
|---|---|---|
| Analysis | Define microservice boundaries, shared dependencies, versioning | 1 day |
| Remote setup | Configure vite-plugin-federation for each app, set shared dependencies |
2 days |
| Host setup | Configure shell, connect remotes, implement Bootstrap pattern with Suspense and ErrorBoundary | 1 day |
| Integration & tests | Verify remote module loading, error handling, mount dynamic remotes | 1–2 days |
| CI/CD | Set up independent deployment for each microservice via GitHub Actions + CDN | 1 day |
Total 5–8 days. The number of remotes affects timeline — each additional app adds 1–2 days.
What's Included in the Work
- Architectural documentation: remote interaction diagram, list of shared dependencies.
- Plugin configuration for all applications (remote and host).
- Implementation of Bootstrap pattern with dynamic loading of remote modules.
- CI/CD setup (GitHub Actions, GitLab CI, or similar) for independent deployment.
- Testing: load verification, network error handling, fallback components.
- Team training: 2-session workshop on microfrontend maintenance.
- Technical support for 2 weeks after delivery.
Contact us for a detailed assessment of your project — we'll prepare a commercial proposal tailored to your stack and requirements.
Common Mistakes When Configuring Vite Module Federation
- Missing
singleton: truefor React: leads to multiple copies and hooks error. - Incorrect remoteEntry path: when deploying to a subdomain, the path must be absolute (https://catalog.example.com/assets/remoteEntry.js).
- Ignoring ErrorBoundary: if a remote is unavailable, the whole app crashes. Always wrap lazy components in
<ErrorBoundary>. - Missing TypeScript types: the plugin does not generate declarations — publish them as an npm package or use
declare module.
How to Ensure Type Safety When Importing Remote Modules
The most reliable way is to publish types from the remote as an npm package (@company/catalog-types). In the host, import the types and use React.lazy with typing:
import type { ProductListProps } from '@company/catalog-types'; const ProductList = React.lazy(() => import('catalog/ProductList')) as React.FC<ProductListProps>; An alternative is to manually write declarations in the host, but this requires synchronization when the remote API changes.
Conclusion
Vite Module Federation is a mature solution for microfrontends if you are ready for the quirks of dev mode. Proper configuration of shared dependencies, dynamic remotes, and CI/CD provide flexibility and performance. Order turnkey setup — we'll design an architecture that scales without losing speed.







