Overview
π‘ My Recommendation for Micro Frontend (Module Federation)
π Use Webpack
Because Module Federation is 100% stable only in Webpack, and your app is explicitly:
βPure Nx Webpack MFE yes use thisβ
For a production-ready MFE architecture:
π₯ Webpack is the best choice.
Rspack is awesome for speed, but MFEs are complex β better stick to Webpack right now.
π§© Final Decision
- β Micro Frontend with Module Federation β Webpack
- β General modern SPA without MFEs β Rspack
npx create-nx-workspace@latest assignment-tracker --preset=ts --packageManager=pnpm
cd assignment-tracker
pnpm add -D @nx/react @nx/module-federation @nx/web webpack webpack-cli webpack-dev-server html-webpack-plugin
pnpm add react react-dom react-router-dom @reduxjs/toolkit react-redux
Add the -w flag to confirm you're intentionally installing to root:
pnpm add -D @nx/react @nx/module-federation @nx/web webpack webpack-cli webpack-dev-server html-webpack-plugin -w
nx g @nx/react:host shell
nx g @nx/react:remote assignments --host=shell
nx g @nx/react:remote watcher --host=shell
π§ Why does Nx need these in the root?
@nx/react,@nx/web,@nx/module-federationβ Nx pluginswebpack,webpack-cli,webpack-dev-server,html-webpack-pluginβ build tooling for all MFEs- Nx expects these packages at the workspace root
So installing to the root is correct for an Nx monorepo.
Creating
nx g @nx/react:host shell
nx g @nx/react:remote assignments --host=shell
nx g @nx/react:remote watcher --host=shell
- Nx created the apps (
shell,assignments,watcher) - But it did not generate
project.jsoninsideapps/assignmentsorapps/watcher - Instead, it stores all config inside the root
workspace.json(orproject.jsonat the workspace root)
This is a change in Nx v22+ (2025) β Nx no longer always uses per-app
project.json. Some generators put everything in the root workspace config.
Folder Structure
RUN COMMADS
or
{
"name": "watcher",
"root": "apps/watcher",
"sourceRoot": "apps/watcher/src",
"projectType": "application",
"targets": {
"serve": {
"executor": "@nx/web:dev-server",
"options": {
"port": 4202,
"host": "localhost",
"webpackConfig": "apps/watcher/webpack.config.js"
}
},
"build": {
"executor": "@nx/web:webpack",
"options": {
"outputPath": "dist/apps/watcher",
"main": "apps/watcher/src/main.tsx",
"index": "apps/watcher/src/index.html",
"webpackConfig": "apps/watcher/webpack.config.js",
"tsConfig": "apps/watcher/tsconfig.app.json"
}
}
}
}
Which one should you use for your Nx Assignment Tracker?
β
Since your remotes (assignments + watcher) are inside the same Nx workspace:
- You can keep it simple:
- Nx dev server will automatically find them and serve the
remoteEntry.jsfor you. - BUT, sometimes Nx dev server fails (like your
paths[1]error). - In that case, using explicit URLs works reliably:
remotes: [
["assignments", "http://localhost:4201/remoteEntry.js"],
["watcher", "http://localhost:4202/remoteEntry.js"],
];
This removes ambiguity, especially if you want to run host before remotes in development.
Recommendation
- For local development: Either approach works, but explicit URLs are safer.
- For production / deployment: You must always use URLs to the deployed
remoteEntry.js, because the host cannot βguessβ the remote path.