Skip to content

Next.js Support is in maintenance mode #3153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ScriptedAlchemy opened this issue Nov 1, 2024 · 58 comments
Open

Next.js Support is in maintenance mode #3153

ScriptedAlchemy opened this issue Nov 1, 2024 · 58 comments

Comments

@ScriptedAlchemy
Copy link
Member

ScriptedAlchemy commented Nov 1, 2024

Deprecation Notice for nextjs-mf

We intend to deprecate (EOL) nextjs-mf, maintained by the core authors of Module Federation.

  • Pages Router will remain "supported," and small, easy fixes will still be back-ported.
  • No new or active development will take place from the core team.
  • Community pull requests will continue to be merged.
  • Vercel should be considered the primary point of contact for anything regarding module federation & next.js. I will provide some support and examples for migrating away from next.

If you are exploring microfrontends, do not use Next.js! It is a hostile framework and Vercel is an adversary of federation


Regarding "RSC Federation" Tweeted by Vercel

I currently have no concrete information regarding this, however my previous statements about it looking like it was just an update to next zones was incorrect.

This is the most recent information: "We did do some upgrades to zones and, independently, RSC Federation and module federation are on our minds (though we don't have anything actionable yet). Two different solutions, two different problem spaces."

If any of this information is inaccurate or new information emerges, I will amend this section.

User Options

Your best options are to contact Vercel or abandon Next.js.

  • Since the Pages Router still works, Next.js 15 is probably safe.
  • Next.js 16 is TBD; if it only requires a minor fix (as with Next.js 15), I will provide a patch.
  • You can use the module-federation/runtime package directly without a compiler plugin, but code sharing will be limited since shared performs build-time chunking. This means remotes must use the same versions of dependencies as hosts, and Next.js builds cannot generate remote entry files—essentially, it can only act as a host system.

We highly recommend moving to a framework that works well with microfrontends:

  • Modern.js works best and will introduce RSC + Federation support in 2025, providing a solid alternative. It powers all of ByteDance and is maintained by their infrastructure team, ensuring excellent support.
  • Remix is also a good option.
  • TanStack looks promising as well.

If anyone wishes to become the primary maintainer of nextjs-mf, you are more than welcome.

Timeline Until Total Deprecation

Barring any unforeseen circumstances, expect nextjs-mf to remain as functional as it is today until mid to end of 2026. This gives you approximately two years to make a plan.

Note: If Next.js 16 breaks Pages Router support beyond an easy fix, version 16 will not be supported.

What This Means:

  • Updates to our runtime packages will still ensure existing unit tests for nextjs-mf pass.
  • Around the end of 2026, nextjs-mf unit tests will be removed from continuous integration.
  • We will no longer track its functionality.
  • If Vercel introduces significant changes that break it before the 2026 EOL, it will be retired ahead of time—assuming it's not a simple adjustment to fix.
  • Most git issues on this repo related to next.js will be closed, file issues with Vercel.

Reasoning

Many framework authors actively collaborate and want to support Module Federation. Next.js is not one of them to date. While there seem to be internal discussions at Vercel, we have seen no indication or received any contact regarding this. Given the track record, doubt anything will materialize

nextjs-mf has involved years of "fighting the framework," and without support from the framework authors, it has been a very slow decline. Considering the substantial time and effort required to keep it somewhat functional, it is simply not worthwhile.

Supporting Next.js has come at the cost of improving the greater ecosystem. Since we stopped focusing on the project at the start of 2024, the Module Federation ecosystem has drastically expanded. This is largely due to reallocating the bandwidth that previously went into nextjs-mf.

As an example, creating Module Federation v2 took about 3 months, supporting modernjs took a few weeks. Next regularly requires months of work

nextjs-mf was initially started in 2021. Early on, there was alignment between Vercel and the Federation group. We enthusiastically submitted a pull request to Next.js to upgrade it to Webpack 5 and advance mutual goals of implementing Module Federation in Next.js. Ultimately, it did not pan out as Turborepo was acquired and a different approach was taken, Next in general has optimized toward bigger and faster monoliths.

I have largely been obligated to maintain this project single-handedly due to the user base being large tech companies—you cannot simply abandon a project when challenges arise. Best efforts have been made over the years to keep the project going. While I have not personally used nextjs-mf in about two years, it has seen two major releases.

I believe I have gone above and beyond for the users of nextjs-mf. While it is indeed disappointing to retire the project, it is time.

its been real, its been good. But it hasn't been real good 👋

Update:
Contact with vercel was made, it appears that they have been experimenting with federation v2.
While nothing is actionable at this time - it is encouraging to see consideration of first-class support.
If support does materialize, we will be happy to adjust this ecosystem to support Vercel's requirements.

@ScriptedAlchemy ScriptedAlchemy changed the title Next.js Support End of Life Next.js Support is in maintenance mode Nov 1, 2024
@ScriptedAlchemy ScriptedAlchemy pinned this issue Nov 1, 2024
@anthonyshew
Copy link

anthonyshew commented Nov 2, 2024

Hey, Zack. We did smooth some rough edges and improve documentation for Multi-Zones with Next.js, and, separately, we're still thinking about and experimenting with solutions for RSC Federation and module federation.

Thank you for all the work you've done for the Next.js community over the years and looking forward to your next projects!

@ScriptedAlchemy
Copy link
Member Author

Hey, Zack. We did smooth some rough edges and improve documentation for Multi-Zones with Next.js, and, separately, we're still thinking about and experimenting with solutions for RSC Federation and module federation.

Thank you for all the work you've done for the Next.js community over the years and looking forward to your next projects!

Glad to hear it! If vercel ever does decide to support module federation - we will be happy to resume support or adjust the ecosystem if there's any concern. Maybe by 2027 vercel will make some moves and users won't be left out in the cold.

It's just too much to support a framework who, as it stands today, doesn't want it.

Appreciate the first class consideration of microfrontends on next.

All the best, you know where to find me. 😉

@tamusjroyce
Copy link

Hi Zach, what alternative frameworks do you suggest?

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 2, 2024

Hi Zach, what alternative frameworks do you suggest?

ModernJS will be the best for federation since it's a first-class feature and supports ssr etc.

Otherwise, anything that isn't owned and operated by vercel should be substantially better. Next has worst support, least features, most problems.

TanStack
ModernJS
Remix
Nuxt
Rsbuild
The Boring Stack
Vite based apps, but no ssr or typescript support.

@prakashmallow
Copy link

@ScriptedAlchemy Does module federation support React.js in the future? I'm asking because React 19 will include an RSC in the next major release.

@ScriptedAlchemy
Copy link
Member Author

Yes, it will. ModernJS will likely ship first with RSC support. Our teams are waiting for v19 stable to arrive, but RSC is already in the quarterly plans. Rspack has already begun work on the Rust side, etc. However, the APIs for RSC have changed a few times, so there’s no point in doing it until we actually have the final API; otherwise, it’s pulling bandwidth away from other work. Once it lands, we will start looking into it. It likely won’t take much work to support, given the historical performance of the infrastructure team.

@lukovskij
Copy link

Hi @ScriptedAlchemy ! I am working with Module Federation 2.0 and the @module-federation/enhanced/runtime package. Could you please clarify if it’s okay to use Next.js (App Router) as a host and import remoteEntry.js at runtime from a React SPA in an NX monorepo?

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 9, 2024

App router is entirely unsupported. My plugin will automatically fail your next build if I detect an app router.
Technically, the federation did always partially work with the app router but caused too many GitHub issues to be opened. Users kept trying to use it even though the documentation stated it doesn't work. So I actively block federation from working if you use the app router at all.

You can try with the vanilla runtime package... but future users are on their own if they attempt to use federation with Next.js.

Beyond migrating away from Next.js - which i will provide offramp support for, users should consider Vercel the primary point of contact for module federation from now on.

If i could block new installs of nextjs-mf, I would.

A safe assumption is this: nothing in my ecosystem will work with anything Vercel owns. If you find a way to make it work, it will be break again soon. Any update of nextjs (major|minor|patch) - expect to spend 6 weeks trying to make things work again, every time. Assume that is your baseline reality

@lukovskij
Copy link

@ScriptedAlchemy thanks! Will we encounter any issues using the @module-federation/enhanced/runtime package solely for runtime in a Next.js host application, loading components only on the client side? We don’t intend to use Module Federation during the build phase and will be loading remote components from a non-Next.js app (runtime only).

@alexandresgraca
Copy link

You could add Nuxt support, there is already a working vite-federation-plugin, but still no Module Federation with SSR support for Nuxt apps. Especially when a Nuxt app is a remote is quite tricky.

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 11, 2024

Module-federation/vite is the official plugin from us. Any others will not be based on the v2 runtime design and thus incompatible with this entire ecosystem.

Nuxt must work with ssr to be considered a alternative imo, otherwise its in the same category as CRA.

If you use rspack + nuxt however, SSR should work, so ill try that

@papers156
Copy link

Can you expand on Pages Router will remain "supported," If using page router is nextjs-mf a reliable and supported plug in?

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 12, 2024

Can you expand on Pages Router will remain "supported," If using page router is nextjs-mf a reliable and supported plug in?

Whatever works today will continue to work until it doesn’t, if vercel ships an update that break the plugin again, and it's not a quick fix, it won't be fixed.

I will ensure the current CI tests pass. If we make a change to federation, the plugin will still get an update in order to make CI tests pass.

Nextjs-mf will receive no new features or development from the core team, beyond making CI green in day to day development.

In 2026, we will begin disconnecting its unit tests from CI and no longer track if it works with our ecosystem updates. Assuming someone in the community does not take over maintenance-expect it to be abandoned in the second half of 2026

@Hareesh108
Copy link

Hi Zach, what alternative frameworks do you suggest?

ModernJS will be the best for federation since it's a first-class feature and supports ssr etc.

Otherwise, anything that isn't owned and operated by vercel should be substantially better. Next has worst support, least features, most problems.

TanStack ModernJS Remix Nuxt Rsbuild The Boring Stack Vite based apps, but no ssr or typescript support.

Hii @ScriptedAlchemy, Is there any other way to do it in the next js?

Please, give some suggestions.

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 13, 2024

The following options:

  • Use module-federation/runtime without any compiler plugin.
  • contact vercel
  • remain on whatever the last version of next.js exists where the plugin still works and never update again
  • take over my role as primary maintainer of the next plugin.

Iframe is a great option for next.js as well

Id definitely suggest contacting vercel or opening git issues there. It's out of my control

@prakashmallow
Copy link

prakashmallow commented Nov 13, 2024

@ScriptedAlchemy Could you please provide the steps for migrating from Next.js to React using module federation?

@ScriptedAlchemy
Copy link
Member Author

Whats react.js? Like a CSR app? like CRA or rsbuild react SPA?

@prakashmallow
Copy link

@ScriptedAlchemy Like React CSR app

@ScriptedAlchemy
Copy link
Member Author

Rsbuild.dev has some great guides. What exactly are you looking for?
In my mind, I'm thinking of copying and pasting the code over and replacing the data loading with something else. 🤔 I don't think a guide is needed for that.

Is there something I am missing?

@fcano-ut
Copy link
Contributor

fcano-ut commented Nov 15, 2024

Hi @ScriptedAlchemy. Thanks for the support you provided so far, I understand the decision.

We have a small Next.js host app we just released to production, and we could consider in our plans to use Remix or other alternative other than Next.js. However, I wanted to get some clarification on this alternative to see if there's a workaround:

Use module-federation/runtime without any compiler plugin.

With that solution, we cannot share dependencies, right? Let's say the host app loads React 18 and a micro-frontend uses React 18, the client would need to download it again?

(So we'd just be using Module Federation as a glorified way of loading JavaScript from another domain, which beats the point in my opinion)

Is my assumption right, or can federation runtime share dependencies as well?

Note: we're only using Next.js for the host, all micro-frontends are static (create-react-app basically)

Thanks 🙏

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Nov 15, 2024

https://module-federation.io/guide/basic/runtime.html#init

Runtime can provide shares to remotes

If you are using something like cra, consider rsbuild.dev 🥰

@FixDev
Copy link

FixDev commented Nov 28, 2024

Hi zack @ScriptedAlchemy i still using module federation with next-mf, i used next.js 13, if i don't upgrade the version of next.js the module federation still can be use with no problem?

@ScriptedAlchemy
Copy link
Member Author

Hi zack @ScriptedAlchemy i still using module federation with next-mf, i used next.js 13, if i don't upgrade the version of next.js the module federation still can be use with no problem?

If it works now. It'll probably keep working.
Should be fine.

@ScriptedAlchemy
Copy link
Member Author

@sokra @mknichel i have opened another PR addressing the review comments of 3276; #3307

@AtnasDev
Copy link

AtnasDev commented Dec 11, 2024

Hi @ScriptedAlchemy .
First of all this is an absolutely great thread to be reading through 🙏

At our company we are about to setup a new product and we are very inclined to use ModuleFederation for our microFE setup. Furthermore, as many other, we are getting fairly hooked on NextJS as the framework of use. I know that this is likely a not functional direction but I wish to state our composition and pick your brain a bit nonetheless.

We will be setting up a host app preferably using NextJS as the shell which dynamically will import the other applications written in React.
The host will work as the sole application which the user interacts with and therefore contain all routing, shared/global state management and template components.

Each microFE will act sort of a component/feature library themselves and expose content in terms of widgets or smaller components with isolated responsibilities.

This will allow us to setup feature based teams and ensure that the general layout and user journey is maintained in 1 single application, the host.

Do you see this being possible to setup using ModuleFederation, likely with NX in a monorepo structure such as follows

frontend-monorepo/
- host/ (NextJS)
- apps/
|- feature1/ (React)
|- feature2/ (React)
|- ...
- libraries/
|- uiComponents/
|- apiWrappers/
|- ...
- configs...

Alternatively we'll place the host app alongside the other applications as such...

frontend-monorepo/
- apps/
|- _host/ (NextJS)
|- feature1/ (React)
|- feature2/ (React)
|- ...
- libraries/
|- uiComponents/
|- apiWrappers/
|- ...
- configs...

@zackarychapple
Copy link
Collaborator

Hi @ScriptedAlchemy . First of all this is an absolutely great thread to be reading through 🙏

At our company we are about to setup a new product and we are very inclined to use ModuleFederation for our microFE setup. Furthermore, as many other, we are getting fairly hooked on NextJS as the framework of use. I know that this is likely a not functional direction but I wish to state our composition and pick your brain a bit nonetheless.

We will be setting up a host app preferably using NextJS as the shell which dynamically will import the other applications written in React. The host will work as the sole application which the user interacts with and therefore contain all routing, shared/global state management and template components.

Each microFE will act sort of a component/feature library themselves and expose content in terms of widgets or smaller components with isolated responsibilities.

This will allow us to setup feature based teams and ensure that the general layout and user journey is maintained in 1 single application, the host.

Do you see this being possible to setup using ModuleFederation, likely with NX in a monorepo structure such as follows

frontend-monorepo/
- host/ (NextJS)
- apps/
|- feature1/ (React)
|- feature2/ (React)
|- ...
- libraries/
|- uiComponents/
|- apiWrappers/
|- ...
- configs...

Alternatively we'll place the host app alongside the other applications as such...

frontend-monorepo/
- apps/
|- _host/ (NextJS)
|- feature1/ (React)
|- feature2/ (React)
|- ...
- libraries/
|- uiComponents/
|- apiWrappers/
|- ...
- configs...

@AtnasDev happy to chat through it with you, shoot me a DM on X or LinkedIn.

@s1davide
Copy link

Rsbuild.dev has some great guides. What exactly are you looking for? In my mind, I'm thinking of copying and pasting the code over and replacing the data loading with something else. 🤔 I don't think a guide is needed for that.

Is there something I am missing?

Hi Zach, what alternative frameworks do you suggest?

ModernJS will be the best for federation since it's a first-class feature and supports ssr etc.

Otherwise, anything that isn't owned and operated by vercel should be substantially better. Next has worst support, least features, most problems.

TanStack ModernJS Remix Nuxt Rsbuild The Boring Stack Vite based apps, but no ssr or typescript support.

Hi Zach, Do you know of any example of rspack react with routes (no matter what method or library), that is SSR and supports React Server Components?

@ScriptedAlchemy
Copy link
Member Author

Rust rsc plugin is still being worked on for rspack

@sbrodrigomartins
Copy link

Hello @ScriptedAlchemy. I noticed that during the thread, there seemed to be some movement between the maintainers of module-federation and Next.js, which resulted in the issue title being changed to "in maintenance mode." Does this actually mean that there is some collaborative effort underway to continue supporting module-federation in Next.js applications?

@ScriptedAlchemy
Copy link
Member Author

Hello @ScriptedAlchemy. I noticed that during the thread, there seemed to be some movement between the maintainers of module-federation and Next.js, which resulted in the issue title being changed to "in maintenance mode." Does this actually mean that there is some collaborative effort underway to continue supporting module-federation in Next.js applications?

You know as much as I do

@npmirajkar
Copy link

Any further updates? on the Jan 18 question above?

@ScriptedAlchemy
Copy link
Member Author

Any information would be posted here. If you see nothing, there is nothing

@digitalhank
Copy link

@anthonyshew is there any true interest from vercel into pursuing first class support for module federation? it is quite clear that users are eager for this and from my perspective @ScriptedAlchemy is doing what he can to meet vercel's needs.

speaking for the products i am involved in, we are will migrate off nextjs unless first class support for module federation is achieved within the year. i bet this holds true for many other teams too. module federation has become an integral part of our operations and allows our big and messy organization to collaborate on a single platform with less friction than ever.

@zackarychapple
Copy link
Collaborator

@digitalhank with the layers PR that @ScriptedAlchemy is landing most likely next week it appears that App Router and Next 15 will work with Module Federation again. From our conversations with the Vercel team they are actively investigating module federation first class support. However with the support and functionality added with layers support that becomes significantly easier.

@prakashmallow
Copy link

@ScriptedAlchemy @zackarychapple We are facing an issue with CSS-in-JS in modern UI component frameworks like Ant Design when used with the Module Federation in Next.js. Is this issue being considered for an upcoming release?

@zackarychapple
Copy link
Collaborator

@ScriptedAlchemy @zackarychapple We are facing an issue with CSS-in-JS in modern UI component frameworks like Ant Design when used with the Module Federation in Next.js. Is this issue being considered for an upcoming release?

Can you open that in a different issue with more details?

@prakashmallow
Copy link

prakashmallow commented Mar 14, 2025

@zackarychapple I have already raised this issue on GitHub, but it has been closed. However, on the Module Federation examples page, they mentioned that CSS-in-JS is not working with the module-federation/next-mf package, and the last two versions do not support it.

FYR - #2317 - Check Note

Could you please reopen the above issue again?

FYI @ScriptedAlchemy

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Mar 15, 2025

Update:

Recently we released Lynx (lynxjs.org) - behind the scenes Ive been working to support federation on Lynx.
It turns out that Lynx relies on layers - it happens to also be what Next uses to implement App Router, and was one of the main reasons I placed the next plugin into maintenance mode.

I have exchanged a few messaged with Tobias (Webpack Founder) & Vercel regarding how to support layers in federation. Unfortunately if i dont know how to do it, Tobias realistically the only other person who would, and he isnt exactly easy to get hold of these days. Theres like 4 people who know how federation works at the lowest levels, so if i dont know then Tobias is the only one who would. Big thanks to Vercel

Current Status

From Vercel

Someone will be looking into MFE tech on their side in the near future in a more dedicated capacity. This is most likely who ill be working with to investigate it jointly. Hopefully we will get to meet in person at one of the Vercel offices at some point, which would most likely grease the wheels

Layers

As of today, the layers feature seems to be working and passing unit tests. Removing the primary roadblock for Lynx, which coincidentally resolves the module sharing problem in App Router as well.

Next utilizes a total of 10 layers - for those unfamiliar with what im talking about. Think of a layer as a shareScope in federation world. Module Federation was written before webpack introduced loader layers, and when layers were added to webpack, nobody added it to federation.

How next uses layers

Before AppRouter, it was simple. require('react') -> node_modules/react/dist/index.js

With AppRouter... "react" resolves to different files depending on who is importing it and what layer that file is in, we call this the issuerLayer

Files in /app/ = layer: 'rsc'

Files within /app/ that have use client = layer: 'ssr'

Files in /pages = layer: undefined

Client Component - require(react) -> next/dist/server/route-modules/app-page/vendored/ssr/react.js
RSC Component - require(react) -> next/dist/server/route-modules/app-page/vendored/rsc/react.js
Page Component - require(react) -> node_modules/react/dist/index.js

If a App Router page import something with "use client" - then it uses 2 "react" veriants (rsc and ssr)

Note that theres another 2 or 3 different "react" variants in the browser as well.

Since next uses 10 layers, its essentially the same as saying 1 app would have to return 10 remoteEntries / use 10 new ModuleFederationPlugins()

How Federation Uses ShareScope

A host app can configure a shareScope in 3 locations.

  1. globally shareScope: 'default'
  2. per remote remotes: {app1: {external: 'http://remote.js', shareScope: 'default'}}
  3. per share shared: {react: {shareScope: 'default'}}

So it would potentially work if we import 5-10 remoteEntry.js files for each app/remote - due to the limitation of container initialization, you can read below why.

The problem is, while shared allows me to assign various share scopes for shared modules, when you initialize a remote, it only supports 1. __webpack_init_sharing__('default') - This means that while other shares may exist in the share scope object, the remote is passed shareScope[default].react - where as we would now need shareScope[default|ssr|rsc|middleware|edge|default] and a few more.

Singleton issues

We have 2 main challanges:

  1. how do you share react twice in the plugin, i cant have an object with 2 keys called react.
    the object key is what is used to match what you import (a request) to check if we want to share it.

So {react: {}, rscRect {}} would work, but..

would require the source code to import from "react" and import from "rscReact" in order for it to work, otherwise rscReact is never matched because nobody has a import statement with the same name, so you end up getting "react" singleton which likely points to the default react/dist/index - and causes the "missmatched react and react dom" error.

  1. Since everything is referred to as "react" and it has to be a singleton - you need "react" to mean 2 different shared modules depending on what file in the host is importing it, so you cant fit "react" on the object twice otherwise it'll overwrite the previous object key in the map.

Contextless layering

Since Federation is what actually yields the modules you import, you cannot traverse the module graph to see what layer it would usually be in, since this step takes place during resolution, not transformation. So while i know the Module.layer will contain the layer i need to match, Im the one who creates the Module in the first place - so I cant just see "what did next layer it as" since at the time of creation, that doesnt exist.

This means federation also needs to know what layer to treat it as. Layers work like regex on a loader. Loaders can apply different resolvers or code transforms based on layer, and those in next are typically applied based on the parent who is importing it, the issuerLayer.

So we need to tell SharePlugin; 1) transform it as layerX 2) do that when the file who imports it is issuerLayer Y.

Core issue

React in federation historically is supposed to only mean 1 thing per host remote connection.
Now React has to mean 3+ things depending on who is importing it in the host or remote and based on the context of that host app. So the remote wont know how its host uses it - potentially it could be used in RSC or SSR or CSR or all of them.

Solution (or at least the major part)

#3276

This pull request introduces several architectural changes to federation to support multiple share scopes, layer, issuerLayer, and request matching that doesnt rely on the key in the shared object of the plugin.

Here is what sharing react looks like now for app router. NOTE: This only represents the server side, client side has additional 2 or 3 more "reacts"

const reactGroup = {
  "react": {
    singleton: true,
    import: false
  },
  'ssr-react': {
    requiredVersion: false,
    request: 'react',
    import: 'next/dist/server/route-modules/app-page/vendored/ssr/react.js',
    singleton: true,
    shareKey: 'react',
    layer: WEBPACK_LAYERS_NAMES.serverSideRendering,
    issuerLayer: WEBPACK_LAYERS_NAMES.serverSideRendering,
    shareScope: [WEBPACK_LAYERS_NAMES.serverSideRendering],
  },
  'rsc-react': {
    requiredVersion: false,
    singleton: true,
    shareKey: 'react',
    request: 'react',
    import: 'next/dist/server/route-modules/app-page/vendored/rsc/react.js',
    layer: WEBPACK_LAYERS_NAMES.reactServerComponents,
    issuerLayer: WEBPACK_LAYERS_NAMES.reactServerComponents,
    shareScope: [WEBPACK_LAYERS_NAMES.reactServerComponents],
  },
};

This now allows us to share something as a specific layer, which would make SWC transform it the right way by manually setting the context of how it should behave.

Additionally, hosts need to __webpack_initialize_sharing__(string|string[]) multiple scopes:

new ModuleFederationPlugin({
   name: 'host',
   //option 1, set globally
   shareScope: ["shared","rsc","ssr","action-browser","api","middleware","instrument","edge-asset","app-pages-browser","default"]
  // option 2 set some scopes per remote
 remotes: {
app2: {
 external: 'someurl',
shareScope: ['rsc','ssr','default'
}
}
})

In the federation runtime, we then need to also assign the scope per remote import.

/******/ 		var chunkMapping = {
/******/ 			"app/favicon.ico/route": [
/******/ 				"(rsc)/webpack/sharing/consume/rsc/react/next/dist/server/route-modules/app-page/vendored/rsc/react.js"
/******/ 			],
/******/ 			"app/page": [
/******/ 				"(rsc)/webpack/sharing/consume/rsc/react/next/dist/server/route-modules/app-page/vendored/rsc/react.js",
/******/ 				"(ssr)/webpack/sharing/consume/ssr/react/next/dist/server/route-modules/app-page/vendored/ssr/react.js"
/******/ 			],
/******/ 			"app/_not-found/page": [
/******/ 				"(rsc)/webpack/sharing/consume/rsc/react/next/dist/server/route-modules/app-page/vendored/rsc/react.js",
/******/ 				"(ssr)/webpack/sharing/consume/ssr/react/next/dist/server/route-modules/app-page/vendored/ssr/react.js"
/******/ 			]
/******/ 		};

and

/******/ 		var moduleToHandlerMapping = {
/******/ 			"(rsc)/webpack/sharing/consume/rsc/react/next/dist/server/route-modules/app-page/vendored/rsc/react.js": {
/******/ 				getter: () => (__webpack_require__.e("vendor-chunks/[email protected]_@[email protected][email protected][email protected]").then(() => (() => (__webpack_require__(/*! next/dist/server/route-modules/app-page/vendored/rsc/react.js */ "(rsc)/../../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react.js"))))),
/******/ 				shareInfo: {
/******/ 					shareConfig: {
/******/ 					  "fixedDependencies": false,
/******/ 					  "requiredVersion": false,
/******/ 					  "strictVersion": false,
/******/ 					  "singleton": true,
/******/ 					  "eager": false,
/******/ 					  "layer": "rsc"
/******/ 					},
/******/ 					scope: ["rsc"],
/******/ 				},
/******/ 				shareKey: "react",
/******/ 			},

With this pull request, module sharing now works with app router - you dont get hit with the dreaded "incorrect react and react dom versions" error.

Next specific problems that remain

Since this is for Lynx, but Next has a common need - I used next app router to test that the layer system works, which it does.

That said, theres some other issues that will likely still hold Nextjs specifically back.

Exposing a module as a layer

While shared works, due to how next uses issuerLayer context to determine how a module will be transformed and how its imports will resolve.

How would you expose "Button.jsx" as SSR, RSC, and CSR? Outside of next this is easy enough to solve since we could create a pattern like /.server.js/ and say anything ending in that is layered as rsc - since the issuer of an exposed module is ContainerEntryModule, next will believe everything exposed is a old school "pages" component. So next internally would need to provide some support or a agreed-upon pattern so we can opt exposed modules into the right loader.

Externals issues

While ive largely hacked and patched my way around this problem for years, its caused many issues for users and quirks in next itself.

Next needs to opt anything thats in "shared" out of the function that makes it a external module - so that server side, anything federation shares will actually be bundled. Today i have a custom runtime plugin to override the runtime module resolving for shared modules for various next internals i know of, for example next/router + react + react-dom always must come from the host, otherwise the app crashes - this makes next to non-next federation work poorly, because federation doesn't actually work correctly in next.

No async boundary

Next doesnt have a dynamic import() before react is used, causing the eager consumption error. How i solved this in the past is to replace the entire templating system for entrypoints. So next doesnt actually use any of the code webpack does for generating the startup code of entrypoints in the bundler ouput. It uses my patch, Next and webpack have the concept of async modules, which app router uses - so ideally some adjustments to how startupEntrypoint works should be done to be federation aware. When federation is in use, webpack should not use webpack_require.O() and switch to using either webpack_require.X (active entry startup, not passive) - I know Tobias knows what im talking about and he most likely could fix this in a few hours or less. Since nobody at webpack has any idea what im talking about, while i know what it needs to do - it seems nobody knows how webpack actually switches into active entry startup mode. So ive decided to not try and fix this again in webpack core, instead im going to focus on adding this capability in Rust for Rspack and leave webpack with the total replacement of the entire entrypoint renderer. Rspack is easier to work on since i have push access to my own bundler and ive already chased this for months at webpack with nobody really having any idea what im talking about.

next/dynamic

using next/dynamic with federation causes hydration errors because dynamic reads from a local json file where the chunk map is - there a hook should be added that would allow someone to register additional chunk maps so that i can pull the references in at runtime and attach them to dynamics existing context object in memory. Last time i tried to make it work with dynamic was nextjs-mf v6, I had to replace require in node with a monkey patch so that i could proxy other values into it from the require cache. Not good. What users have to do today is React.lazy it to avoid hydration errors in the client.

"Hot reloading prod server"

There needs to be a way to make webpack "forget" its loaded remoteModules and chunks, causing it to fetch them again when someone redeploys. Currently i nuke the entire require cache and instantiate the entrypoints in the same order they were originally - this is overkill. My runtime supports refetching modules, and has its own module cache - but webpack does not.

What needs to be shared?

I have hunted down what i think needed to be shared for pages router, but it would be good to get an official list or have vercel export a constant containing the share configurations needed for federation itself.

Ending notes

From my end; the primary blocker is now removed. I will proceed with rewriting the layers system in Rust, but do have some other priorities in front of that effort.

nextjs-mf will not utilize the new layer capabilities once the PR merges - but I have another branch where i did the testing for layers itself on app router. When Vercel makes contact on next steps, we can work together on any changes needed in next.js itself.

Federation can now support AppRouter, but the inherent constraints of Next.js remain and these require first class support / considerations, without them - id rather not bait users with something that appears to work only to get hit various problems that burnt me out before and provided the userbase with a suboptimal experience caused by trying to reverse engineer next every few weeks :P

Either we support it well or not at all.

I do not mean this in a negative way! All indications from Vercel give me some optimism. But I want to be cautious about giving anyone, especially myself - false hope.

Ill post any updates or news, assume this is the most up-to-date location for information. We all know the same information, which is whats in this thread already

If you want to see the app router experimentation i tried on next to verify the layers work: #3596

@digitalhank
Copy link

@ScriptedAlchemy Wonderful writeup. Excited to see what the future brings.

@mlstubblefield
Copy link

I've been following this for years and am excited to hear some updates. Vercel has been trying (for years) to push us towards a mono repo (which we will not do). Our current solution is a private npm package for all of our MFEs that's a hassel to update.

@zackarychapple
Copy link
Collaborator

I've been following this for years and am excited to hear some updates. Vercel has been trying (for years) to push us towards a mono repo (which we will not do). Our current solution is a private npm package for all of our MFEs that's a hassel to update.

100%! The great thing about Next supporting MF will supporting both monorepo and polyrepo setups and the freedom for orgs.

@Imangali-Sauyrbay
Copy link

Hi Zack,

First of all — massive thanks for your work on Module Federation and the surrounding ecosystem. It’s been an eye-opener, and I’ve been following closely with growing excitement. I’m a big fan of what you're building, and I’ve been meaning to switch to MF for a while now.

I’m mainly a Go/C dev, so performance is kind of a personal obsession 😅. That’s where things get tricky.

While I’m eager to adopt MF, no current SSR framework I’ve tested comes close to the raw RPS performance of Next.js (5k+ in synthetic benchmarks).
But… as you probably guessed, Next.js has been a nightmare. Even setting up something like /:lng?/:city?/... is a jungle of rewrites, middlewares, and edge-case debugging.

And now with the planned deprecation of nextjs-mf — I’m totally on board with that, honestly — but I’m stuck with no solid exit plan.

What I’ve tested so far:

  • Nuxt: ~2k RPS

  • Remix: ~1.5k RPS

  • Modern.js: not even hitting 900 RPS in my tests, and feels like a fragile mix of loosely coupled parts (React-Router, Helmet, Styled Components, etc.). I also hesitate to build long-term on a ByteDance-led stack — if something becomes inconvenient, it might vanish overnight 😅

  • Svelte: impressive at ~10k RPS, but not MF-friendly and a whole different mental model

To be fair, I fully understand that synthetic RPS benchmarks are meaningless once I/O comes into play — but even then, they highlight how well-optimized a framework is for SSR in its bare metal form. That initial ceiling says a lot about how much room I’ll have left after I/O enters the picture.

To make things worse, Next.js just had a critical CVE (CVE-2025-29927 — auth bypass in middleware with a 9.1/10 CVSS score). That really shook my confidence in depending on it for critical systems.

So here’s my question:

Is there a React-based SSR framework you'd personally trust for production that plays nice with MF (or is at least "MF-adaptable") and doesn’t fight you every step of the way?

I’m not looking for plug-and-play magic — just something reliable that won’t collapse under traffic or get in the way of building modular systems.

Really appreciate your time if you get a chance to reply 🙌

Cheers,
Imangali – just a performance-obsessed dev from Almaty 🇰🇿
Loves poking runtimes and tearing things apart for fun 😄
Not another Next.js survivor™ (Trying to escape middleware hell since 2023 💀)

@ciandt-crodrigues
Copy link
Contributor

Nextjs just added first party support for rspack I wonder if something could be done on top of that instead of supporting nextjs-mf library

@zackarychapple
Copy link
Collaborator

I know I'm most likely not the Zack you're talking to but wanted to chime in too.

Hi Zack,

First of all — massive thanks for your work on Module Federation and the surrounding ecosystem. It’s been an eye-opener, and I’ve been following closely with growing excitement. I’m a big fan of what you're building, and I’ve been meaning to switch to MF for a while now.

I’m mainly a Go/C dev, so performance is kind of a personal obsession 😅. That’s where things get tricky.

While I’m eager to adopt MF, no current SSR framework I’ve tested comes close to the raw RPS performance of Next.js (5k+ in synthetic benchmarks). But… as you probably guessed, Next.js has been a nightmare. Even setting up something like /:lng?/:city?/... is a jungle of rewrites, middlewares, and edge-case debugging.

Curious if you tried tanstack start? Also if you're looking for pure RPS are you needing a fully functional framework or would vanilla react server components with Node be acceptable?

And now with the planned deprecation of nextjs-mf — I’m totally on board with that, honestly — but I’m stuck with no solid exit plan.

Next.js support for Module Federation longer on the deprecation path, as you can see from Rspack adding support for Next.js as shared by both the Rspack team here and by Vercel in their update here. This will make it significantly easier for us to add support for Next.js in a much easier to support manner. Additionally it looks like the Next team is also interested in collaborating to add first class support into Next.

What I’ve tested so far:

Depending on requirements you have this should be significantly faster with vanilla Node + Fastify | Express + React Server Components. Would love to see your test repo for this.

  • Nuxt: ~2k RPS
  • Remix: ~1.5k RPS
  • Modern.js: not even hitting 900 RPS in my tests, and feels like a fragile mix of loosely coupled parts (React-Router, Helmet, Styled Components, etc.). I also hesitate to build long-term on a ByteDance-led stack — if something becomes inconvenient, it might vanish overnight 😅

Ouch, what indication do you feel that it would disappear overnight? ByteDance isn't Google lol. I've seen zero indication that things just drop off the face of the planet with them. However that is a very painful experience and not the one they want to see.

  • Svelte: impressive at ~10k RPS, but not MF-friendly and a whole different mental model

To be fair, I fully understand that synthetic RPS benchmarks are meaningless once I/O comes into play — but even then, they highlight how well-optimized a framework is for SSR in its bare metal form. That initial ceiling says a lot about how much room I’ll have left after I/O enters the picture.

Facts, this is why benchmarks are helpful, but not the be all, end all.

To make things worse, Next.js just had a critical CVE (CVE-2025-29927 — auth bypass in middleware with a 9.1/10 CVSS score). That really shook my confidence in depending on it for critical systems.

That is good feedback for the Vercel / Next team. Though it is patched and many systems have had CVEs I tend to correlate reliability with how quickly things get patched, and how well that is communicated with the community.

So here’s my question:

Is there a React-based SSR framework you'd personally trust for production that plays nice with MF (or is at least "MF-adaptable") and doesn’t fight you every step of the way?
I've personally hear a lot of good things about Tanstack Start and I believe @jherr has an example of MF and Start in the works, but I may be wrong.

I’m not looking for plug-and-play magic — just something reliable that won’t collapse under traffic or get in the way of building modular systems.
Sounds like you're building something fun!

Really appreciate your time if you get a chance to reply 🙌

Cheers, Imangali – just a performance-obsessed dev from Almaty 🇰🇿 Loves poking runtimes and tearing things apart for fun 😄 Not another Next.js survivor™ (Trying to escape middleware hell since 2023 💀)
Cheers!

@zllkjc
Copy link
Contributor

zllkjc commented Apr 14, 2025

Modern.js: not even hitting 900 RPS in my tests, and feels like a fragile mix of loosely coupled parts (React-Router, Helmet, Styled Components, etc.). I also hesitate to build long-term on a ByteDance-led stack — if something becomes inconvenient, it might vanish overnight 😅

Hello, I'm a Modern.js developer. Thank you for your feedback on Modern.js. Let me try to talk the points you mentioned.

  1. At its core, Modern.js is still a framework based on Rsbuild and React Router. Other features like Helmet and style-component are optional.

  2. As @zackarychapple mentioned, I don't see any signs that Modern.js will be suddenly deprecated - at least not within the next 3-5 years. Additionally, it needs to compatibility with large number of ByteDance products, so there won't be any crazy breaking changes.

not even hitting 900 RPS in my tests

We've indeed received some feedback on SSR performance recently, and we're currently working on optimizing it. If possible, could you provide more information about your tests ?

@Imangali-Sauyrbay
Copy link

Hey @zllkjc!

First of all — thanks a ton for your thoughtful and respectful reply 🙌 And sorry for the delay — I owe one to Gmail notifications for not showing this until a couple of days later 😅

I want to take a moment to clarify one thing up front:

👉 Modern.js is genuinely one of the most impressive stacks I’ve tested. Despite some SSR quirks I mentioned, it's currently my top candidate for the next project — and here's why:

  • Build speed is insane — nothing else I tried even comes close.
  • Out-of-the-box support for both Module Federation and Garfish is a massive win.
  • The architecture is thoughtfully modular, and it actually feels good to work with.

That said, the concerns I raised still hold true from my personal experience — especially around:

  • SSR perf out of the box (I'll get to that below),
  • and the learning curve caused by relatively sparse docs/examples, especially in English. The fact that most of the community resources are in Chinese can be a bit limiting — not a blocker, but it adds friction.

Regarding the perf tests:

The numbers (~900 RPS initially) came from a very simple setup:

  • I followed the official Quick Start guide to scaffold an SSR app.

  • The app was completely vanilla — no business logic, no routes added.

  • I tested the production build (modern build && modern start / node ./output/index.mjs) using a small wrapper script around wrk, something like:
    for i in {1..15}; do wrk -t10 -c10 -d30s http://localhost:8080 >> results.log; done
    awk '/Requests\/sec/ { total += $2; count++ } END { print "Average RPS:", total / count }' results.log

  • I also tested it under PM2 just in case, but results were roughly the same.

  • I did tweak a few things — set log level to error-only, tuned cache/stale times — and managed to bring it closer to 1.3k–1.4k RPS, which is already much better and more usable.

These tests were all run on my local machine:

  • CPU: Intel i9-14900HX (32 threads)
  • RAM: 32GB
  • OS: Ubuntu 24.04 running in WSL2 (on Windows 11)
  • Benchmark context: wrk -t10 -c10 -d30s simulates 10 concurrent clients across 10 threads; repeated 10–15 times per scenario to average out anomalies.

Not a production-grade test environment 😅, but close enough to reflect meaningful deltas in cold vs warm SSR paths.

And about the ByteDance comment — I totally get how that might've come across as overly cautious or based on stereotypes. That wasn’t the intention, and especially being from Almaty 🇰🇿 (we're practically neighbors with China 😄), I really don’t mean to dismiss the effort or stability behind Modern.js.

The concern comes more from a place of trying to plan long-term around a core framework. When you build infra around something, you want to be sure the team behind it is going to keep it stable and evolving with the community. Seeing active engagement like yours here definitely helps ease that concern. So thank you for showing up and keeping the conversation going — it makes a difference 🙏

If you’d like me to test something specific, or try a canary/dev version with recent SSR perf improvements, I’d be happy to do that and share some structured results!

Again, big thanks to you and the team for pushing the boundaries — it’s clear you’re building something unique, and I’m rooting for it 🚀

Cheers from Almaty,
Imangali

@Imangali-Sauyrbay
Copy link

Imangali-Sauyrbay commented Apr 16, 2025

Hey Zack @zackarychapple!

Haha — you might not have been the Zack I originally meant, but turns out you’re exactly the one this reply needed 😄 Appreciate you jumping in — and sorry for the delay, Gmail decided to play hide-and-seek with the notification 😅

On TanStack Start & Raw RPS Needs
I’ve been following TanStack Start with genuine excitement — the routing model clicks with how I think about modular architecture. But since it’s still in beta, I’m cautiously waiting for things to stabilize a bit more before making the leap.

My RPS obsession came from a very specific place: running high-traffic SSR apps on limited hardware (read: cheap VPS life 😆). That led me down a rabbit hole of performance experiments, and I eventually realized:

Most SSR frameworks max out before serious I/O kicks in. Once you hit databases, microservices, or even light middleware logic — it all drops off sharply.

🔬 What I’ve Been Testing

After being frustrated with conventional frameworks, I started hacking together a custom setup:

Go backend

  • GoFiber for raw performance
  • a-h/templ — a React-like, type-safe templating engine in Go
  • Vite for frontend bundling
  • And a tiny DOM-native frontend framework I’m building — reactive, lazy-loaded, no hydration, no VDOM.

Here’s a taste of what templ looks like (pure Go):

package main

templ Hello(name string) {
  <div>Hello, { name }</div>
}

templ Greeting(person Person) {
  <div class="greeting">
    @Hello(person.Name)
  </div>
}

Templ looks like React-JSX, but no VDOM, no hydration — just fast, clean HTML straight from the backend.

⚙️ The Frontend Framework (inspired by HTMX + Alpine + React) (So far it's a conceptual idea 😅)

This is where it gets fun — components are connected declaratively:

<div ... data-component="some-sender|in-view"></div> // |hover, |click, |lazy, |eager etc

And then hooked up like this:

class SmthSender extends Component {
  @Reactive("& .someSendOutput|text") // or even |html, |attr:class, |attr:style, |attr:data-output, or render function for complex data like |render:listOutput
  protected output: string = "";

  public constructor(@Inject("someservice") private service: SomeService) {
    super();
  }

  protected async onClick() {
    this.get(".btn").text("Sending...");
    const res = await this.service.send();
    this.output = res.message;
  }

  protected listOutput(list: List[]) {
    return this.templates.render("some-list", list);
  }
}

Initial framework for the application:

const app = new Application(options)

app.bound("someservice", () => import("path/to/service"))
app.register("some-component", () => import("path/to/component")) // and further just <div data-component="some-component">

app.registerGlob(() => import.meta.glob("./components/**/*.ts"))

app.start()

Features (or: how I accidentally reinvented PHP, but faster)

  • @Reactive("& .selector|html"):
    Declarative reactivity — no proxies, no reactivity traps. Just string bindings and targeted updates.
    Think Vue, but without a framework. Or brain damage.

  • @Inject("name"):
    Dependency Injection without tree-shaking anxiety. No bundling unused services, no webpack gymnastics.
    If it's not used — it's not loaded. If it's needed — it's just there. Lazy, like a true backend dev.

  • DOM access via .get(".btn")
    DOM access scoped inside the component root. No refs, no useRef(), no forwardRef(), no “why did this rerender?”
    Just vanilla DOM with modern manners.

  • Runtime?
    ~5–10kb. No hydration, no VDOM, no fiber trees, no 300kb bundles, no internal slot contexts.
    It’s so small, it feels like cheating.

Component classes are dynamically loaded via import() as needed. No hydration mismatch issues, just raw HTML with light interactivity. This means SSR-first architecture, with client-side JS only when necessary — a sort of middle-ground between HTMX and Vue.

If React is a full-stack UI framework, this is more like "do-what-I-say" runtime. No magic. Just results.
And as a bonus — the only RFC you’ll ever need is #include "button.html" 😆

🧟‍♂️ Welcome to the resurrection of PHP — but this time with taste

Honestly, it's starting to feel like the early 2000s all over again — but faster:

  • You don’t need to think about Module Federation.
  • You don’t need to pre-bundle a microfrontend architecture.
  • You just… serve HTML from different services via one NGINX gateway.

That’s it.
No federation. Just federated HTML.

🧪 Benchmarking Setup

Responding to your question about perf testing:

  • All benchmarks used vanilla projects created via official Quick Start docs (Modern.js, Remix, Nuxt, etc.)

  • Ran with:

for i in {1..15}; do wrk -t10 -c10 -d30s http://localhost:8080 >> results.log; done
awk '/Requests\/sec/ { total += $2; count++ } END { print "Average RPS:", total / count }' results.log
  • Host system:

    • CPU: i9-14900HX (32 threads)

    • RAM: 32GB

    • OS: Ubuntu 24.04 WSL2 on Windows 11

So, not production-grade — but consistent enough to highlight gaps between setups 😅.

⚠️ Thoughts on Next.js + Rspack

I was honestly surprised (in a good way) to see Rspack getting first-class support in Next.js right after my original comment — that gives me hope for a cleaner MF future in the Next ecosystem.

As for Modern.js — my earlier concerns were more instinctive than informed (being in Almaty 🇰🇿, we do have a regional “distance” from Chinese stacks). But the response from @zllkjc was excellent and definitely eased some of that uncertainty.


Would Love Your Thoughts!

I know my setup is a bit unconventional, but I’m chasing that dream stack where:

  • SSR is fast and predictable
  • The DOM stays clean
  • And the client only runs what it needs, when it needs it

Would love to know what you think about this direction — especially with your background in MF and performance-focused builds.

Thanks again for everything you’re building — and for taking the time to chime in 🙌

Cheers again, and thanks for pushing the ecosystem forward!

embrace jquery.js
reject shadow-dom.js
return to ejs, eta, and good-enough

@ScriptedAlchemy
Copy link
Member Author

Modern.js: not even hitting 900 RPS in my tests, and feels like a fragile mix of loosely coupled parts (React-Router, Helmet, Styled Components, etc.). I also hesitate to build long-term on a ByteDance-led stack — if something becomes inconvenient, it might vanish overnight 😅

Hello, I'm a Modern.js developer. Thank you for your feedback on Modern.js. Let me try to talk the points you mentioned.

  1. At its core, Modern.js is still a framework based on Rsbuild and React Router. Other features like Helmet and style-component are optional.
  2. As @zackarychapple mentioned, I don't see any signs that Modern.js will be suddenly deprecated - at least not within the next 3-5 years. Additionally, it needs to compatibility with large number of ByteDance products, so there won't be any crazy breaking changes.

not even hitting 900 RPS in my tests

We've indeed received some feedback on SSR performance recently, and we're currently working on optimizing it. If possible, could you provide more information about your tests ?

Yeah ill back this up. Modernjs has been around for a while and will continue to be around for a while.
Its simply not feasible to switch to something else, for a similar reason we created Rspack. At scale, its cheaper to rewrite webpack in rust than it is to move thousands of products to something else.
Since most of web app run on modernjs, id say its safe.

Also consider that the company has more headcount and revenue than Meta (facebook), the inconvenience would be the stack vanishing, not the stack becoming an inconvenience IMO. Even if we wanted to abandon it, it would take years to wind down at this scale and we would have to replace it with something that was cost effective to adopt that serves all the requirements we have. Id not be too concerned about a rug pull. the perf concerns are valid for sure.

@ScriptedAlchemy
Copy link
Member Author

ScriptedAlchemy commented Apr 18, 2025

Update

I was at the Vercel offices today...as promised - youd be kept in the loop.

Partnering with Next

We (Rspack Team) have formed a broad partnership with Next.js on various build infrastructure needs that both of us seem to be solving and we share many underlaying parts of the rust ecosystem. We have been working closely since the start of the year on improving SWC as well as shipping Rspack support in Next 15.3. While federation is technically outside this loop - the primary problems that forced me to retire this plugin appear to be effectively solved.

No access to Vercel team was essentially a death sentence for the plugin, but at the time of its creation I was young and foolish 😆 However, rspack did go a long way in establishing a reliable communication pipeline.

Next & Federation

Naturally I seized the opportunity today to weasel federation into a conversation. I was rewarded with a ton of clarity & general vibe from Next.js about the possibility of actually seeing support.

Heres the general summary of where we stand (not set in stone, so dont quote me)
No specific opposition to federation assuming the following statements

  • It does not become a resource drain on the team to support
  • It does not drastically alter the product
  • it does not constrain the teams ability to iterate in the future & box them into rigidity.
  • We do not introduce public apis that users have to deal with, and they have to document.

All reasonable expectations, so i think that as much as possible will remain outside the main next codebase and in the community tier.
Maybe a few constants like DEFAULT_SHARES can be exported from next, as well as a few private apis or hooks that can be added to add a little more flexibility that i need. Ill see what would be needed, but I dont think much needs to change in next - its just very difficult to do this from the outside.

I am ~80% confident that the required accommodations for Module Federation will materialize.

As such, I will begin the process of unblocking AppRouter in nextjs-mf - technically it now works, I just have something that detects app router and throw a error. Though since moving the plugin into maintenance mode, I have completely stopped working on it and have not tested how it beyond removing the block, updating some shared modules and checking if a page renders without crashing. I would still advise keeping the federation parts in /pages as I am unsure how it will behave - if you want to try, in theory 'use client' may work.

Timeline

Currently, I spend most of my time in the Next.js/Rspack repo, working to pass the remaining failing tests of next-rspack (we are at around 96%) - my plan is to gradually reallocate time to federation related tasks, and split time between rspack support and federation support. Since Im in both the compiler and next repos now constantly, it seems like a good time to address federation.

Timeline is pretty loose, there are still several areas of discovery and exploration we need to take a closer look at.
So i do anticipate various rough edges, Ill attempt to detail the ones im aware of in the next section.

We have identified that an ideal time for both sides to dig a little deeper would potentially be in about ~4-6 weeks time. No promises, but this provides some timeframe where details can be hammered out. In the meantime, I will restore some of the capabilities in the plugin and perform preliminary work needed on my end, which mostly is shipping new versions of the plugin, use a handful of hacks to try and test the functionality and see what happens.

Known areas of concern

  • While sharing now works, exposed modules always are exposed as 'use client' due to how next determines if something is rsc or ssr / client module. So we need a secondary rule in the build config of next that allows me to specify "treat this as if it were imported by /app/page.ts (process it as a rsc module)
  • Next/dynamic causes hydration errors, we have to use react.lazy which creates waterfalls. Next dynamic needs a hook so i can inject / resolve next/dynamic css/js from federaitons mf-manifest and not exclusively the compile-time json file next uses today.
  • "Hot reloading" the prod server when a remote updates. This is a little buggy for some users, we need an actual solution or Vercel sanctioned way to "restart" the webpack runtime when remotes update. Note: if you deploy on vercel - and if vercel wanted to do so, they have the infrastructure to manage this similar to zephyr-cloud. They could use their eixisting skew protection and just expire the host lambda when a remote changes. Such a method would eliminate the need for hot reloading the node side, since you would not get a hydration error when because the server is stuck on a different version of remote than what the browser loads when fetching latest.
  • No async boundary. I solved this in webpack, but have not ported it to Rust - without it, federation cannot work in next.js. This is the most challenging area. While i can easily change rspack, there is a similar builtin mechanism that handles async startup - when you use RSC it goes into async mode - but nobody has any idea how it works. So i really need another 10min call with Tobias since he is almost certainly the only person who knows what im talking about and could tell me how it works, then i could update the mechanism slightly so that its enabled automatically when federation is in use, and finally update rspack/webpack to do this

Please note, nothing is set in stone, there is no guarantee - but Im confident that things will now pan out. Ultimately a deeper evaluation needs to take place - but conversations demonstrate at the very least that meaningful considerations will take place to evaluate a path forwards and if a viable path is found. We will most likely see improved support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests