Siddhant DevalAuthor
Senior Full-Stack Engineer·Sep 22, 2026·15 min read
Module Federation 2.0: Dynamic Remotes, Type Safety, and Runtime Plugins
Module Federation 2.0 shifts the paradigm from static remote URLs at build time to runtime manifest resolution — enabling zero-downtime rollbacks, canary deployments, and cross-boundary type safety without a full rebuild.
Technical Series
Micro-Frontend Architecture
Part 4 of 9
Module Federation 2.0: Dynamic Remotes, Type Safety, and Runtime Plugins
A micro-frontend is not a smaller app — it is a domain boundary enforced at the deployment layer. If you can't explain the business capability it owns, you haven't drawn the boundary yet.
In Part 3, the remote URL was hardcoded into the host's build config:
javascript
This works. It also means that if the Checkout team deploys a bug and you need to roll it back, you must rebuild and redeploy the App Shell — a process that takes 8–15 minutes in most CI systems. During those 8–15 minutes, broken code runs in production for every user.
Module Federation 2.0 solves this. It shifts the paradigm from "static remote URLs baked into the host at build time" to "runtime manifest resolution" — where the host fetches a pointer file from a CDN at startup and the pointer file determines which remote version to load. Rolling back is a one-line CDN file update: 30 seconds, no rebuild.
1. The Manifest Architecture
1.1 The Problem With Hardcoded URLs
A hardcoded remote URL creates a build-time dependency between the host and the remote's deployment:
The host's build config couples it to the remote's deployment. Independent deployability — the entire point of the architecture — is broken.
1.2 The Manifest Solution
Module Federation 2.0 introduces a
manifest.json file as an indirection layer between the host and the remote's actual chunk URL:javascript
The manifest file is what changes with every deployment:
json
To roll back from v1.2.5 to v1.2.3: update
mf-manifest.json to point to the v1.2.3 remoteEntry.js. The host loads the new manifest on next page load. No rebuild. No host redeployment.
Expand

Expand
2. Type Safety Across Boundaries
2.1 The Type Boundary Problem
In a monolith, importing a component gives you full TypeScript safety:
typescript
In a Module Federation setup, the import is dynamic and crosses a deployment boundary:
typescript
A developer changes the
Cart component's props in the Checkout remote — renames itemCount to cartCount. The host still compiles. CI passes. Production breaks at runtime when itemCount is undefined.2.2 @module-federation/dts-plugin
The solution is generating and distributing TypeScript declaration files (
.d.ts) as part of the remote's build:javascript
javascript
After running the host build, TypeScript declarations are available:
typescript
Crucial Requirement
@module-federation/dts-plugin type bundles are build-time integration tests. A prop rename in a remote that breaks a host consumer will fail the host's tsc compilation — catching the contract violation before deployment, not after. Treat dts errors as CI blockers, not warnings.bash
3. Runtime Plugins: Lifecycle Interception
3.1 The Plugin API
Module Federation 2.0 introduces a runtime plugin API that lets you intercept federation lifecycle events. This is the correct injection point for production concerns like circuit-breaking, telemetry, and A/B routing:
typescript
javascript
3.2 Telemetry Plugin
typescript
Pro Tip & Optimization
Never put circuit-breaking logic inside
try/catch blocks in your React components. Circuit-breaking is a cross-cutting concern that belongs in the federation runtime, not in application code. Runtime plugins are architecturally correct injection point — they intercept all remote loads uniformly, regardless of which component triggered the import.3.3 A/B Routing Plugin
typescript
4. Decentralized Routing
4.1 The Routing Ownership Problem
In a standard Module Federation setup, the App Shell owns all top-level routes and maps them to remotes. This creates a coupling: when the Checkout team adds a new sub-route (
/checkout/gift-cards), they must submit a PR to the shell's routing config and wait for a shell deployment.Module Federation 2.0's
@module-federation/router allows each remote to declare its own route segments:typescript
typescript
Performance / Safety Warning
Decentralized routing requires a formal route prefix ownership contract. If Checkout claims
/checkout/* and later Catalog tries to claim /checkout/products, you have a conflict with no compile-time detection. Document route prefixes as a formal interface in your architecture decision record and enforce them in code review.5. Import Maps as an Alternative
5.1 When Import Maps Are Sufficient
Browser-native
<script type="importmap"> allows you to remap bare module specifiers to URLs without any bundler plugin:html
Import Maps are baseline-available across all modern browsers as of 2024 and require zero tooling configuration. They are the correct choice when:
- Your team count is small (2–3 remotes)
- Your remotes are stable and infrequently updated
- You do not need shared dependency negotiation
5.2 Where Import Maps Fall Short
| Capability | Module Federation 2.0 | Import Maps |
|---|---|---|
Shared dependency negotiation (singleton) | ✅ Runtime scope negotiation | ❌ Every consumer loads its own copy |
| TypeScript type sharing | ✅ dts-plugin | ❌ Not supported |
| Runtime plugins (circuit-breaking, telemetry) | ✅ Plugin API | ❌ Not supported |
| Dynamic manifest resolution | ✅ mf-manifest.json | ❌ Map is static in HTML |
| Lazy loading on demand | ✅ | ✅ |
| Zero tooling requirement | ❌ Requires MF plugin | ✅ Pure HTML |
Import Maps cannot share a singleton React instance across multiple ESM modules. If both your shell and your checkout remote import
react from the CDN, they get two separate instances — the bug from Part 2 returns. For any system where remotes consume React context or hooks from the host, Import Maps are not viable.Summary
| Concept | Rule |
|---|---|
| Hardcoded remote URLs | Couple host build to remote deployment — use manifests instead |
mf-manifest.json | Stable pointer file; update it to deploy, update it to rollback |
@module-federation/dts-plugin | Type-safe cross-remote imports; dts errors are CI blockers |
| Runtime plugins | Circuit-breaking, telemetry, A/B routing — inject here, not in application code |
| Decentralized routing | Each remote owns its route prefix; document ownership formally |
| Import Maps | Viable for small, stable remote sets; cannot share singleton deps |
What's Next
In Part 5, we build the App Shell — the only component in the system with global authority. We define its responsibilities precisely (layout, routing, error containment), draw the exact Error Boundary topology that prevents a remote crash from taking down the shell, and implement the circuit-breaker pattern using the runtime plugins from this article. Part 5 → The App Shell: Container Architecture, Routing, and Error Boundaries
References
Research & Synthesis Note
This article was developed with AI-assisted deep search, specification cross-referencing, and technical research synthesis.
#Module Federation 2.0#Rspack#Dynamic Remotes#TypeScript#CDN#Micro-Frontends
Technical Series
Micro-Frontend Architecture
Part 4 of 9