mf-integrate
Original:🇺🇸 English
Translated
Integrate Module Federation into an existing project — add provider (exposes modules) or consumer (loads remote modules) configuration. Use when the user wants to add Module Federation to an existing Rsbuild / Rspack / Webpack / Modern.js / Next.js / Vite project, set up a remote, create a host app, or quickly consume the demo provider to see MF working. Default role is consumer.
6installs
Sourcemodule-federation/core
Added on
NPX Install
npx skill4agent add module-federation/core mf-integrateTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →MF Scaffold — Add Module Federation to an Existing Project
Step 1: Detect project
Call the Skill (pass ) to collect MFContext.
mf-context$ARGUMENTSIf no bundler can be detected (no , , , , , found), this is likely a new project. Tell the user:
rsbuild.configrspack.configwebpack.configmodern.confignext.configvite.configThis looks like a new project. Run the following command to scaffold a full Module Federation project:bashnpm create module-federation@latest
Then stop.
If MF is already configured (MFContext shows existing or ), inform the user what is already configured and ask if they want to add/modify the configuration or stop.
remotesexposesStep 2: Gather parameters
Ask the user the following questions (combine into one AskUserQuestion call):
-
Role — What role should this app play?
- — loads modules from remote apps (default)
consumer - — exposes modules to other apps
provider - — exposes modules and loads remote modules
both
-
App name — What should the MF name be for this app?
- Suggest the field from
name(snake_case, no hyphens). Hyphens are not allowed in MF names.package.json
- Suggest the
-
Role-specific:
- If consumer or both: Do you want to connect to the public demo provider to see MF working immediately, or configure your own remotes?
- — use the public demo provider (default for consumers)
demo - — I'll specify my own remote URLs
custom
- If provider or both: What module(s) do you want to expose? Provide pairs, e.g.
key: path. If unsure, use./Button: ./src/components/Button.tsxas a default.'.' : './src/index'
- If consumer or both: Do you want to connect to the public demo provider to see MF working immediately, or configure your own remotes?
Step 3: Build the MF config object
Construct the MF config based on the gathered parameters:
Remote entries (for consumer / both)
Demo provider (use when user chose ):
demots
remotes: {
'provider': 'rslib_provider@https://unpkg.com/module-federation-rslib-provider@latest/dist/mf/mf-manifest.json',
},The demo provider exposes a React component at . The user can import it in their app:
'provider'tsx
import ProviderApp from 'provider';Custom remotes (use when user chose ):
Ask the user to provide remote entries in the format , then use them as-is.
customname: urlExposes (for provider / both)
Use the entries provided by the user. Example:
ts
exposes: {
'./Button': './src/components/Button.tsx',
},Shared deps
Read to check which frameworks are present. Set singletons accordingly:
package.json- If +
reactpresent: add both asreact-dom{ singleton: true } - If present: add as
vue{ singleton: true } - If both (rare): add all as singletons
Step 4: Generate files
Apply the correct pattern for the detected bundler:
Rsbuild
Detected by: / in project root.
rsbuild.config.tsrsbuild.config.js4a. Create module-federation.config.ts
module-federation.config.tsts
import { createModuleFederationConfig } from '@module-federation/rsbuild-plugin';
export default createModuleFederationConfig({
name: '<app-name>',
// exposes: { ... }, // provider / both only
// remotes: { ... }, // consumer / both only
shareStrategy: 'loaded-first',
shared: {
// react + react-dom or vue — from Step 3
},
});4b. Modify rsbuild.config.ts
rsbuild.config.tsAdd to the plugins array:
pluginModuleFederationdiff
+import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
+import moduleFederationConfig from './module-federation.config';
export default defineConfig({
plugins: [
pluginReact(),
+ pluginModuleFederation(moduleFederationConfig),
],
});4c. Install
bash
pnpm add @module-federation/rsbuild-pluginModern.js
Detected by: / in project root.
modern.config.tsmodern.config.js4a. Create module-federation.config.ts
module-federation.config.tsts
import { createModuleFederationConfig } from '@module-federation/modern-js-v3';
export default createModuleFederationConfig({
name: '<app-name>',
// exposes: { ... }, // provider / both only
// remotes: { ... }, // consumer / both only
shared: {
// react + react-dom or vue — from Step 3
},
});4b. Modify modern.config.ts
modern.config.tsdiff
+import { moduleFederationPlugin } from '@module-federation/modern-js-v3';
export default defineConfig({
plugins: [
appTools(),
+ moduleFederationPlugin(),
],
});4c. For consumer: add type paths
Modify to resolve remote types:
tsconfig.jsondiff
{
"compilerOptions": {
+ "paths": {
+ "*": ["./@mf-types/*"]
+ }
}
}4d. Install
bash
pnpm add @module-federation/modern-js-v3Rspack
Detected by: / in project root.
rspack.config.tsrspack.config.js4a. Modify rspack.config.ts
/ rspack.config.js
rspack.config.tsrspack.config.jsAdd and :
ModuleFederationPluginexperiments.asyncStartupdiff
+const { ModuleFederationPlugin } = require('@module-federation/enhanced/rspack');
module.exports = {
+ experiments: {
+ asyncStartup: true,
+ },
plugins: [
+ new ModuleFederationPlugin({
+ name: '<app-name>',
+ // exposes: { ... }, // provider / both only
+ // remotes: { ... }, // consumer / both only
+ shared: {
+ // from Step 3
+ },
+ }),
],
};Note:requires Rspack > 1.7.4.experiments.asyncStartup
4b. Install
bash
pnpm add @module-federation/enhancedWebpack
Detected by: / in project root.
webpack.config.tswebpack.config.js4a. Modify webpack.config.js
webpack.config.jsdiff
+const { ModuleFederationPlugin } = require('@module-federation/enhanced/webpack');
module.exports = {
+ experiments: {
+ asyncStartup: true,
+ },
plugins: [
+ new ModuleFederationPlugin({
+ name: '<app-name>',
+ filename: 'remoteEntry.js',
+ // exposes: { ... }, // provider / both only
+ // remotes: { ... }, // consumer / both only
+ shared: {
+ // from Step 3
+ },
+ }),
],
};4b. Install
bash
pnpm add @module-federation/enhancedNext.js
Detected by: / / in project root.
next.config.tsnext.config.mjsnext.config.jsDeprecation warning:only supports Pages Router (not App Router) and is no longer actively maintained. For new projects, consider using Rsbuild or Modern.js instead.@module-federation/nextjs-mf
4a. Modify next.config.mjs
next.config.mjsdiff
+import { NextFederationPlugin } from '@module-federation/nextjs-mf';
const nextConfig = {
webpack(config, options) {
+ config.plugins.push(
+ new NextFederationPlugin({
+ name: '<app-name>',
+ filename: 'static/chunks/remoteEntry.js',
+ // exposes: { ... }, // provider / both only
+ // remotes: { // consumer / both only
+ // remote: `remote@http://localhost:3001/static/${options.isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
+ // },
+ shared: {},
+ extraOptions: {
+ exposePages: true,
+ enableImageLoaderFix: true,
+ enableUrlLoaderFix: true,
+ },
+ })
+ );
return config;
},
};4b. Enable local Webpack
Add to :
.env.localNEXT_PRIVATE_LOCAL_WEBPACK=true4c. Install
bash
pnpm add @module-federation/nextjs-mf webpack -DVite
Detected by: / in project root.
vite.config.tsvite.config.js4a. Modify vite.config.ts
vite.config.tsdiff
+import { federation } from '@module-federation/vite';
export default defineConfig({
plugins: [
+ federation({
+ name: '<app-name>',
+ // exposes: { ... }, // provider / both only
+ // remotes: { ... }, // consumer / both only
+ shared: {
+ // from Step 3
+ },
+ }),
],
});4b. Install
bash
pnpm add @module-federation/viteStep 5: Auto-insert remote component (consumer / both only)
Skip this step entirely for provider-only role.
Ask the user:
Do you want me to automatically add the remote component to your app's entry so you can see it working right away?
If the user says no, just show the code snippet as a reference and move on to Step 6.
If the user says yes:
5a. Locate the entry file
Search for the entry component file in this priority order:
| Bundler | Candidates (in order) |
|---|---|
| Rsbuild | |
| Modern.js | |
| Webpack / Rspack | |
| Next.js | |
| Vite | |
Read the first file that exists. If none found, tell the user which file to modify manually and show the snippet — do not attempt blind writes.
5b. Determine remote name and import path
Use the remote name from the config generated in Step 4:
- If demo provider: remote name is , import path is
provider'provider' - If custom remotes: use the first remote name the user specified
5c. Edit the entry file
Add the import at the top of the file (after existing imports) and render the component inside the existing JSX return.
For React (Rsbuild / Rspack / Webpack / Vite)
Add import after the last existing import line:
tsx
import ProviderApp from 'provider';Insert inside the existing JSX return. Find a natural place — inside a , after existing content. Do not restructure the component; just append the element.
<ProviderApp /><div>For Modern.js ()
src/routes/page.tsxSame pattern — add import and render in the returned JSX.
<ProviderApp />For Next.js ()
pages/index.tsxSame pattern — add import and render in the returned JSX.
<ProviderApp />5d. Add TypeScript declaration (if TypeScript project)
Check if exists. If it does, create (or add to an existing / if present):
tsconfig.jsonsrc/remote.d.tssrc/declarations.d.tssrc/env.d.tsts
declare module '<remote-name>' {
const Component: React.ComponentType;
export default Component;
}Replace with the actual remote name (e.g., ).
<remote-name>providerProvider: how to verify the exposed module
Tell the user that after running the dev server, the manifest will be available at:
- Rsbuild / Rspack / Webpack / Modern.js:
http://localhost:<port>/mf-manifest.json - Next.js:
http://localhost:<port>/static/chunks/remoteEntry.js
Another app can reference this app as a remote using:
ts
remotes: {
'<app-name>': '<app-name>@http://localhost:<port>/mf-manifest.json',
},Step 6: Summary
Output a concise summary:
- What files were created or modified
- What packages were installed
- How to start the dev server (use existing script from )
package.json - Next steps (e.g., add more remotes, configure shared deps, set up type generation)