.agents/skills/mf-integrate/SKILL.md
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.
npx skillsauth add brGuirra/funkonation mf-integrateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Call the mf-context Skill (pass $ARGUMENTS) to collect MFContext.
If no bundler can be detected (no rsbuild.config, rspack.config, webpack.config, modern.config, next.config, vite.config found), this is likely a new project. Tell the user:
This looks like a new project. Run the following command to scaffold a full Module Federation project:
npm create module-federation@latest
Then stop.
If MF is already configured (MFContext shows existing remotes or exposes), inform the user what is already configured and ask if they want to add/modify the configuration or stop.
Ask the user the following questions (combine into one AskUserQuestion call):
Role — What role should this app play?
consumer — loads modules from remote apps (default)provider — exposes modules to other appsboth — exposes modules and loads remote modulesApp name — What should the MF name be for this app?
name field from package.json (snake_case, no hyphens). Hyphens are not allowed in MF names.Role-specific:
demo — use the public demo provider (default for consumers)custom — I'll specify my own remote URLskey: path pairs, e.g. ./Button: ./src/components/Button.tsx. If unsure, use '.' : './src/index' as a default.Construct the MF config based on the gathered parameters:
Demo provider (use when user chose demo):
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 'provider'. The user can import it in their app:
import ProviderApp from 'provider';
Custom remotes (use when user chose custom):
Ask the user to provide remote entries in the format name: url, then use them as-is.
Use the entries provided by the user. Example:
exposes: {
'./Button': './src/components/Button.tsx',
},
Read package.json to check which frameworks are present. Set singletons accordingly:
react + react-dom present: add both as { singleton: true }vue present: add as { singleton: true }Apply the correct pattern for the detected bundler:
Detected by: rsbuild.config.ts / rsbuild.config.js in project root.
module-federation.config.tsimport { 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
},
});
rsbuild.config.tsAdd pluginModuleFederation to the plugins array:
+import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
+import moduleFederationConfig from './module-federation.config';
export default defineConfig({
plugins: [
pluginReact(),
+ pluginModuleFederation(moduleFederationConfig),
],
});
pnpm add @module-federation/rsbuild-plugin
Detected by: modern.config.ts / modern.config.js in project root.
module-federation.config.tsimport { 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
},
});
modern.config.ts+import { moduleFederationPlugin } from '@module-federation/modern-js-v3';
export default defineConfig({
plugins: [
appTools(),
+ moduleFederationPlugin(),
],
});
Modify tsconfig.json to resolve remote types:
{
"compilerOptions": {
+ "paths": {
+ "*": ["./@mf-types/*"]
+ }
}
}
pnpm add @module-federation/modern-js-v3
Detected by: rspack.config.ts / rspack.config.js in project root.
rspack.config.ts / rspack.config.jsAdd ModuleFederationPlugin and experiments.asyncStartup:
+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:
experiments.asyncStartuprequires Rspack > 1.7.4.
pnpm add @module-federation/enhanced
Detected by: webpack.config.ts / webpack.config.js in project root.
webpack.config.js+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
+ },
+ }),
],
};
pnpm add @module-federation/enhanced
Detected by: next.config.ts / next.config.mjs / next.config.js in project root.
Deprecation warning:
@module-federation/nextjs-mfonly supports Pages Router (not App Router) and is no longer actively maintained. For new projects, consider using Rsbuild or Modern.js instead.
next.config.mjs+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;
},
};
Add to .env.local:
NEXT_PRIVATE_LOCAL_WEBPACK=true
pnpm add @module-federation/nextjs-mf webpack -D
Detected by: vite.config.ts / vite.config.js in project root.
vite.config.ts+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
+ },
+ }),
],
});
pnpm add @module-federation/vite
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:
Search for the entry component file in this priority order:
| Bundler | Candidates (in order) |
|---|---|
| Rsbuild | src/App.tsx, src/App.jsx, src/App.js |
| Modern.js | src/routes/page.tsx, src/routes/page.jsx |
| Webpack / Rspack | src/App.tsx, src/App.jsx, src/App.js, src/index.tsx, src/index.jsx |
| Next.js | pages/index.tsx, pages/index.jsx, pages/index.js |
| Vite | src/App.tsx, src/App.jsx, src/App.js |
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.
Use the remote name from the config generated in Step 4:
provider, import path is 'provider'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:
import ProviderApp from 'provider';
Insert <ProviderApp /> inside the existing JSX return. Find a natural place — inside a <div>, after existing content. Do not restructure the component; just append the element.
For Modern.js (src/routes/page.tsx)
Same pattern — add import and render <ProviderApp /> in the returned JSX.
For Next.js (pages/index.tsx)
Same pattern — add import and render <ProviderApp /> in the returned JSX.
Check if tsconfig.json exists. If it does, create src/remote.d.ts (or add to an existing src/declarations.d.ts / src/env.d.ts if present):
declare module '<remote-name>' {
const Component: React.ComponentType;
export default Component;
}
Replace <remote-name> with the actual remote name (e.g., provider).
Tell the user that after running the dev server, the manifest will be available at:
http://localhost:<port>/mf-manifest.jsonhttp://localhost:<port>/static/chunks/remoteEntry.jsAnother app can reference this app as a remote using:
remotes: {
'<app-name>': '<app-name>@http://localhost:<port>/mf-manifest.json',
},
Output a concise summary:
package.json)development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
development
Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn/ui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn init", "create an app with --preset", or "switch to --preset".
development
Diagnose Module Federation type issues across three categories: (1) producer type file generation failures (TYPE-001), (2) consumer failing to pull remote types, (3) tsconfig not configured to consume remote types. Use when the user encounters TS type errors, missing @mf-types folder, or cannot consume remote module types.
development
Check Module Federation shared dependency configuration: detect shared/externals conflicts, antd/arco transformImport blocking shared deps, and multiple versions of the same shared package in build artifacts. Use when shared dependencies fail to be shared, or host and remote load duplicate instances of a library.