Repository navigation
Module Federation Support #1480
Description
This issue serves as a central place to track the support of Module Federation in Metro.
Module Federation has become the standard for decomposing large web-based applications. Through Re.Pack and Module Federation, we've seen growing excitement around the potential for federated mobile applications and a standards-based approach to building mini-apps in React Native. For long-term stability, we believe it would be ideal for Module Federation to be supported directly within Metro. This would align Metro with other bundlers that support Module Federation natively, such as webpack, Rspack, and Rolldown, as well as Vite via a community plugin.
Enabling this may require adding new capabilities to Metro and making some adjustments on the Module Federation side. A single tracking issue helps consolidate discussions and progress around these changes.
We’re excited to see this move forward!
cc @thymikee @robhogan @ScriptedAlchemy @valorkin
Update April 17, 2025
Example created and moved to the Module Federation organization here
Update April 15, 2025
@jbroma and @Esemesek did some preliminary research together and taking into account the insights from @ScriptedAlchemy, have pinpointed few areas that would need tackling in order to get the Module Federation working:
- - virtual modules support for the runtime modules & shared dependencies - currently there is no support for that (can be emulated by creating modules on the filesystem)
- - bundle splitting - looks like the biggest issue to enable this seems to be a system of deterministic module ids, since right now the numbers are just assigned based on order of usage
- - scoping of module system in remote containers - in webpack/rspack the containers ship with their own module system to isolate the non-shared parts - this could be as easy as wrapping the remote in IIFE but needs more research
- - async boundary support - any async actions before the first render will cause a runtime error, therefore
We're currently working on a basic prototype to uncover the other requirements, but it seems like we could skip code-splitting altogether for the time being and package everything into the remote container (remoteEntry.js).
Initial Roadmap
- finish the minimal prototype of connecting 2 apps built with metro together -
Updated: April 17, 2025 - extend the range of supported MF options (like non-singleton shared deps or version-first share startegy)
- develop the official MF plugin in the mf core repo based on the prototype implementation (or simply move it)
- ship the necessary PRs to metro & react-native core packages (like community-cli-plugin)
Activity
martamoc commentedon Mar 31, 2025
@Esemesek
ScriptedAlchemy commentedon Mar 31, 2025
Main areas of consideration.
when sharing a module, all imports resolve to a "virtual" module who then calls our runtimes loadShare() method
so import "react" => loadShareSync("react")
The system is async, so if the module is not preloaded, in order to make eager module consumption work - we usually make end users have a import() somewhere in the codebase before shared modules are used, then we will hoist all async requirements to that boundary and await the requirements there.
There is however a loadShareSync as well. But you'd still need to first call preload to ensure you await the async task somewhere that a async boundary can be tolerated.
follow same construct as shared modules, they are async and we create a virtual module that initializes the containers upfront, then pulls the exposed module from the container as needed or at the async boundary
import 'remote/button' => loadRemote('remote/button')
We loop over the plugin configs to find all remotes associated in the build and build up the configuration, then call init({name, remotes,shared}); this must happen at application startup
banerjeesouvik commentedon Apr 14, 2025
This will be very helpful. In one of our native expo projects, we are trying to create the web build a an MFE, which we will import in another web app. This solves our use case.
zackarychapple commentedon Apr 15, 2025
@ScriptedAlchemy any feedback on this part?
zackarychapple commentedon Apr 17, 2025
Initial prototype has been created and has been uploaded to the module federation organization.
crherman7 commentedon Apr 24, 2025
I love that module federation is becoming more of conversation with respect to metro-bundler! Great progress 👌
I’ve been working on ReChunk, a system for dynamically loading React Native components and functions at runtime. It uses a custom runtime resolver I built called metro-requirex, which taps into Metro’s module ID system to require modules on the fly.
One major challenge has been the lack of a public API for resolving module IDs outside of Metro’s internal bundling phase. Right now, I’m relying on internal behavior to make it work, which isn’t ideal. A stable, documented way to access Metro’s module resolution or generate a runtime-consumable manifest would go a long way toward enabling dynamic delivery patterns like this.
Excited about the future improvements and updates!
ElielC commentedon Apr 24, 2025
Our team has come to rely on Expo's packages and the Expo CLI`s CNG. We are looking into creating micro-apps, so this would be extremely helpful.
Really looking forward to this!
jbroma commentedon Apr 25, 2025
Hey 👋
Module Federation in Metro prototype update:
Since we have no access to
top level awaitin Metro, this felt like the biggest obstacle to deal with right now. Module Federation sometimes requires an an async startup - especially whenversion-firstsharing strategy is used (essentially it fetches all remote containers upfront and determines the highest versions of dependencies that can be used in the setup)I've managed to get around this by creating a wrapper for the main RN entrypoint component and we can wait for MF runtime to finish initialising. We simply wrap the main entrypoint in
React.Suspenseand import the entrypoint insideReact.lazyin which we also await MF initialisation to finish. SinceReact.Suspensecan accommodate a fallback component to display in the meantime, the wrapper optionally accepts a fallback component as well. The only limitation is that no shared dependency except for React and React Native can be used before this point. Here's how it looks in the app that acts as a host:here is a more detailed list of things accomplished this week (all merged):
version-firstshare strategyimport: falsein shared dependency configshareStrategyconfiguration optionEsemesek commentedon May 16, 2025
Hey 👋,
Here's some update on the Module Federation with Metro prototype:
exposesfield in the plugin configuration. To enable this, we introduced some necessary modifications to Metro itself in our fork which we will try to upstream.mf-manifest.jsonfiles as remote entry points, aligning with Module Federation conventions.bundle-mf-remote– this command was introduced to bundle remote modules and output the split chunks into a directory. This enables us to produce production bundles and prepare them to be hosted externally, without relying on the Metro dev server - thus emulating target CDN environments.Current focus:
loadRemotefrom@module-federation/runtimeand for full feature parity with the MF spec, we need to handle the following scenarios:refactor: prevent reinitializing `global.$RefreshReg$` (#1510)
feat: process HMR `registerBundle` calls from same origin only (#51821)
feat: allow reuse of `ReactRefresh` instance (#1513)
refactor: prevent reinitializing `global.$RefreshReg$` (react#1510)
zackarychapple commentedon Sep 1, 2025
Two packages have now been merged into Module Federation Core that are for Metro usage.
https://www.npmjs.com/package/@module-federation/metro
https://www.npmjs.com/package/@module-federation/metro-plugin-rnef
Huge thanks to everyone involved already.
jbroma commentedon Sep 2, 2025
Happy to say that we have shipped everything initially planned and more:
While we still have few PRs to merge into Metro, we've shipped with Babel plugins that bridge the gaps and allow for earlier testing / adoption of Module Federation in Metro (those are scheduled for removal in the future when the stable version of MF integration will be released).
Docs should become available soon, showing how to use it in React Native projects 💡
Thank you everyone involved, especially @zackarychapple @robhogan @Esemesek & @ScriptedAlchemy 🚀
Nsttt commentedon Sep 2, 2025
🚀
maitriyogin commentedon Sep 25, 2025
Hi and huge thanks for this initiative!
I've just tried this out with RN 0.81.4, but got a weird error regarding setImmediate being undefined..
Also, the latest metro version you get from a fresh RN project, is different to the expected 82.3 that module federation libs seem to need.
I was wondering if:
There is a suggested RN version ?
Will Expo be supported?
Do you need to use RNEF?
Many thanks for your awesome work!
zackarychapple commentedon Sep 25, 2025
Thank you for the love! I can answer these two quick.
@HigorAlves, @Nsttt what versions are y'all using?
maitriyogin commentedon Sep 26, 2025
super!
I've had to go down to RN 0.80.0
Awaiting the expo suport with great expectation.
maitriyogin commentedon Sep 26, 2025
Hiya, I've been battling with getting my host to read a producer manifest.
It's kind of resulted in me having to install:
"react-native-polyfill-globals": "^3.1.0",
"web-streams-polyfill": "^3.3.3"
Which module federations seems to require for fetching?
Why?
Having done this it still doesn't fetch the manifest. The manifest is being served.
I've written a little script that reads and verifies it.
So why wouldn't the host app be able to fetch the manifest??
If I remove the polyfill stuff I get the following
The bundle is being served ...
Any ideas?
Nsttt commentedon Sep 26, 2025
Hey @maitriyogin are you able to jump into either the Zephyr discord or the Module Federation discord and post the question there ?
Probably easy to debug there and we can talk about making a reproduction :)
Apart from that, remoteEntryExports is usually that it fetched the manifest but it's having issues with one of the following calls after that.
maitriyogin commentedon Sep 29, 2025
of course apologies
ElielC commentedon Oct 28, 2025
Any news on Expo support?
jbroma commentedon Nov 3, 2025
Hey! The Expo support is in the works here: module-federation/core#4080
What's left to do is the CLI integration, and thats still in progress at this moment
raffidahmad commentedon Jan 16, 2026
Hi, the PR seems to have been closed due to being stale. Is there any expectation of this being released soon?
drodmun commentedon Jan 16, 2026
Any ETA for when this PR will be reopened and handled?