Quick Answer:
A proper setup for module federation involves configuring a host and remote application using Webpack 5. The core steps are: 1) Install webpack@5 and ModuleFederationPlugin, 2) Configure the plugin in each app’s webpack.config.js to expose or consume modules, and 3) Ensure shared dependencies are correctly managed. For a basic two-app setup, a senior developer can get the initial integration working in about 4-6 hours, but production-readiness takes days of testing.
You are probably looking at Module Federation because you have multiple frontend apps that feel like separate islands. They share nothing, or they share too much in the worst possible way—through copy-pasted code. You want a cleaner architecture, maybe micro-frontends. The promise is alluring: build things independently, deploy them separately, but have them work together seamlessly in the browser. The reality of the setup for module federation, however, is where most teams get stuck. It is not about copying a config file. It is about understanding a new model of application composition.
I have been building composite applications since the days of iframes and PHP includes. The fundamental problem has always been the same: how do you get discrete pieces of software to talk without creating a tangled mess? Module Federation is the latest and most elegant answer Webpack has given us, but its elegance is deceptive. The initial setup for module federation is straightforward. Making it work for a real business, with real developers, on a real timeline, is where the art comes in.
Why Most setup for module federation Efforts Fail
Here is what most people get wrong about the setup for module federation. They treat it as a purely technical, plug-and-play configuration. They follow a tutorial, get the “Hello World” of a remote component loading, and declare victory. The real failure happens weeks later.
The first major mistake is misunderstanding “shared” dependencies. You see a list of libraries like React, ReactDOM, or a UI kit. The tutorial says to add them to the shared array. So you do. But you do not specify versions or singleton rules. Now you have two different versions of React loading in the same page, or worse, your host app’s React context is not the same as your remote app’s React context. Your application breaks in subtle, maddening ways that are nearly impossible to debug because everything looks connected.
The second mistake is architectural vagueness. Teams do not decide upfront what constitutes a “module.” Is it a single button? A whole page route? A data-fetching hook? Without clear boundaries, you end up with a spiderweb of cross-remote imports that defeats the entire purpose of isolation. You have just recreated a monolith, but now it is distributed across network boundaries with all the latency and failure modes that implies. The setup for module federation succeeds or fails at the whiteboard, not in the code editor.
I was brought into a fintech project last year where a team of bright engineers had spent three months trying to adopt Module Federation. They had a dashboard app, a reporting app, and a admin panel—all in React, all built by different squads. They could load components from each other, but the user’s authentication state would randomly disappear. Clicks in the remote module wouldn’t trigger updates in the host. They had a working technical setup, but a broken user experience. When I looked at their configs, the issue was immediate. They were sharing react and react-dom, but the host was on React 18.2.0 and the reporting remote was pinned to 18.0.0. The singleton: true flag was set, but Webpack was trying to be clever and load both. We locked every remote to an exact, shared version. The “bug” was fixed in 20 minutes. The real fix was establishing a governance rule: shared dependencies are controlled by the platform team, not the individual squads.
The Setup That Actually Works in Production
Forget the toy examples. Let us talk about the setup for module federation that survives contact with the real world.
Start with a Contract, Not a Config
Before you write a single line of Webpack configuration, define the contract between your applications. What is the host allowed to expect from the remote? Is it a React component with a specific prop interface? A function that returns a promise? Document this like an API spec. This contract becomes the foundation of your exposes configuration. It forces you to think about the public API of your module, which naturally leads to more stable, versionable interfaces.
Be Ruthless About Shared Dependencies
Your shared configuration is the most critical part of the setup. Do not just list packages. Be explicit. Use the object syntax to demand a singleton, specify a required version, and even tell Webpack not to eager-load it. For example: shared: { ‘react’: { singleton: true, requiredVersion: ‘^18.2.0’ }, ‘my-ui-kit’: { singleton: true, eager: true } }. Marking your design system as eager: true ensures it loads immediately, preventing a flash of unstyled content. This level of control is what separates a prototype from a production system.
Implement a Runtime Error Boundary
Network calls fail. Your remote app’s deployment might be broken. Your setup for module federation must account for this. You cannot just import(‘remote/Component’) and hope. Wrap your dynamic remote loading in an error boundary and have a clear fallback UI—a degraded experience is better than a white screen. This is not a Module Federation feature; it is an architectural necessity that Federation makes critical.
Module Federation’s power isn’t in splitting your app—it’s in enabling federation. The difference is control. A split codebase is just pieces. A federated one is an ecosystem with rules, and the setup is where you write those rules.
— Abdul Vasi, Digital Strategist
Common Approach vs Better Approach
| Aspect | Common Approach | Better Approach |
|---|---|---|
| Dependency Sharing | List packages in a shared array. Hope for the best. | Use object syntax to enforce singletons, pin versions, and control loading behavior (eager/lazy). |
| Module Design | Expose large, complex components or entire features with tight coupling. | Expose simple, contract-driven components or utilities with loose coupling. Think “API-first.” |
| Error Handling | Assume the remote is always available. The app crashes if it’s not. | Implement runtime error boundaries and fallback UIs for every federated module load. |
| Development Workflow | Run all remotes simultaneously or constantly switch configs to test. | Use a dedicated development host that can point to locally running remotes or deployed stubs. |
| Versioning & Deployment | Deploy remotes and host simultaneously; tight coupling leads to downtime. | Design remotes to be backward compatible. Host can reference a specific version of a remote, allowing independent deploys. |
Looking Ahead to 2026
The setup for module federation is evolving. By 2026, I see three clear trends. First, framework meta-tools like Vite and Next.js will have first-class, stable Federation support. The painful Webpack configuration will be abstracted behind simpler framework-specific APIs. This is already bubbling, but it will be mainstream.
Second, we will see the rise of “Federation-as-a-Service” layers. Managing the discovery, versioning, and health checks of dozens of remote modules is an operational headache. Dedicated tools or internal platforms will emerge to act as a registry or control plane for your federated ecosystem, moving beyond the basic static URLs in config.
Finally, the pattern will mature beyond just React or JavaScript. We are already seeing experiments with WebAssembly modules and backend-for-frontend services being federated. The principle of runtime integration of independent pieces will apply to more parts of the stack. Your setup will need to think about types, not just at build time with TypeScript, but at runtime with schema validation for cross-module communication.
Frequently Asked Questions
Is Module Federation only for huge applications?
No, but its value increases with scale. For a small app, the complexity overhead isn’t worth it. The sweet spot is when you have multiple teams working on distinct features that need to be composed into a single user interface, or when you need to integrate a legacy app piece-by-piece.
Can I use Module Federation with Vite or Next.js?
Yes, but it’s not as native as Webpack yet. Vite has community plugins that implement the Federation protocol. Next.js has experimental support, but it conflicts with some of its core optimizations. By 2026, I expect both to have stable, official support.
How do you handle state management across federated modules?
Carefully. You avoid sharing complex state directly. Instead, use patterns like custom events, a lightweight state bus, or pass state down as props from the host. Keep the state management within each remote simple and lift only the necessary shared state to the host or a dedicated shared library.
How much do you charge compared to agencies?
I charge approximately 1/3 of what traditional agencies charge, with more personalized attention and faster execution. My model is built on direct expertise, not layers of account management and junior staff.
What’s the biggest performance pitfall?
Over-fragmenting your application into too many tiny remotes. Each remote is a separate network request. The latency and overhead can crush your initial load time. Federate at the feature level, not the component level, and use aggressive caching and preloading strategies.
Look, the setup for module federation is a gateway. It lets you build software in a more scalable, team-oriented way. But it is not a magic bullet. It trades build-time complexity for runtime complexity. Your success hinges on treating it as an architectural discipline, not a Webpack plugin. Start small. Define a solid contract for one module. Get the shared dependency configuration ironclad. Prove it works in your environment. Then, and only then, think about expanding the federation. The goal is not to use a cool technology. The goal is to build software that can change and grow without breaking.
