Help us improve
Share bugs, ideas, or general feedback.
From mfe-skills
Reviews and generates micro-frontend code against eight boundary rules, covering Module Federation, Native Federation, Single SPA, and governance for feature flags, edge strategy, and SSR ownership.
npx claudepluginhub lucamezzalira/mfe-skills --plugin mfe-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/mfe-skills:reviewing-mfe-boundariesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Reviews and generates micro-frontend code against the eight boundary rules from *Building Micro-Frontends* (O'Reilly). All rules are tool-agnostic. Full rule definitions, violation signals, and code-checkable patterns are in `references/rules.md` — load it when you need the detail for a specific rule.
Provides micro-frontend architecture vocabulary, principles, and a decisions framework. Use when evaluating MFE adoption, defining boundaries, choosing composition strategies, or reviewing architecture for distributed monoliths.
Guides building, configuring, and deploying microfrontends on Vercel using microfrontends.json, multi-zone routing, asset prefixes, and the @vercel/microfrontends package.
Scaffolds a new DataHub Micro Frontend app using Webpack Module Federation. Generates all required boilerplate files and guides through setup.
Share bugs, ideas, or general feedback.
Reviews and generates micro-frontend code against the eight boundary rules from Building Micro-Frontends (O'Reilly). All rules are tool-agnostic. Full rule definitions, violation signals, and code-checkable patterns are in references/rules.md — load it when you need the detail for a specific rule.
On every activation, apply this summary table directly — no file load needed:
| Rule | What to check in code | Severity |
|---|---|---|
| 1 — Business subdomain | Name reflects a business capability, not a UI element | High |
| 2 — Minimal API surface | Fewer than 5 props; no full domain objects passed | Critical |
| 3 — Hide implementation details | No direct imports from another MFE's internals | Critical |
| 4 — Events not shared state | No shared store; shell handles shell:* only; domain events peer-to-peer or URL | Critical |
| 5 — Independent deployment | No versioned URLs in shell config; no build-time MFE imports; no CI pipeline coupling | High |
| 6 — Isolate failure | Every remote mount has a fallback in the shell | High |
| 7 — Coarse-grained | Nesting depth > 1 (MFE inside MFE); more than 3 MFEs per view | High |
| 8 — Single-team ownership | One team in CODEOWNERS; no cross-team sign-off on internals | High |
For full rule definitions and violation signals: load references/rules-core.md.
For framework-specific patterns (MF v2, Angular/Native Federation, Single SPA): load references/rules-toolchain.md.
For URL routing ownership (shell first segment, MFE deeper paths): load references/routing-ownership.md.
For fix patterns and step-by-step remediation: load references/remediation.md when the user asks how to fix a violation or requests a migration plan.
If no boundaries exist yet, ask about the highest-priority unknown first — one question per turn. Do not generate implementation code until each check is resolved.
Check 1 — Team ownership Ask: "Which team will own this micro-frontend end-to-end — design, development, deployment, and operations?" If unresolved: do not generate implementation code. Ask the user to install the micro-frontend-canvas skill and complete a canvas iteration (see https://github.com/lucamezzalira/mfe-canvas).
Check 2 — Domain identification Ask: "What business capability does this represent? What user journey step does it enable?" If unclear: recommend the micro-frontend-canvas skill before implementation. Do not generate a full Canvas worksheet from this skill. A boundary without a named domain is not ready for code.
Check 3 — Decisions framework Ask: "Is this a vertical or horizontal split, and how will it be composed — client-side or server-side?" If unresolved: generate a skeleton with a placeholder composition comment and note which decision is still needed.
Once all three are confirmed, apply the rules as design constraints from the first line of code — retrofitting is significantly more expensive than designing correctly upfront.
When generating any MFE code, apply these defaults without being asked. Examples are shown per toolchain — apply the pattern that matches the user's stack.
URL routing — shell first segment only; MFE owns depth below (Rule 7):
routes.json + remotes.json) so adding/removing an MFE does not require shell code changes or redeploy for MFE-internal pages/product/:id under /catalog); new sub-pages are MFE-only deploys<a>, <Link>, navigate(), etc.) — enforce URL depth ownership, not a specific router API// ✓ Shell — manifest-driven first segment (wildcard → remote)
// routes.json: { "path": "/catalog/*", "scope": "catalog_mfe", "module": "./CatalogApp" }
routes.map((r) => <Route key={r.scope} path={r.path} element={<RemoteMount ... />} />)
// ✓ Catalog MFE — hardcoded routes under basename (no shell change when adding pages)
<BrowserRouter basename="/catalog">
<Routes>
<Route path="/product/:productId" element={<ProductDetail />} />
</Routes>
</BrowserRouter>
// ✗ Shell — domain sub-route
<Route path="/catalog/product/:productId" element={...} />
Shell platform events — allowed; domain events in shell — not (Rules 4, 7):
catalog:*, checkout:*, cart:*)shell:alert, shell:modal:open, etc.; horizontal peers may use domain events MFE-to-MFE, not via shell handlers// ✓ MFE → shell chrome
platformBus.emit('shell:alert', { message: 'Saved', variant: 'success' })
// ✗ Shell listens to business events
platformBus.on('catalog:productSelected', handler)
Load references/routing-ownership.md for full patterns.
Shell mounting — always include a fallback in the shell, not inside the micro-frontend (Rule 6):
{/* React / Module Federation */}
<ErrorBoundary fallback={<CheckoutFallback />}>
<CheckoutMicrofrontend userId={userId} cartId={cartId} />
</ErrorBoundary>
// Angular / Native Federation — shell route with fallback on load failure
{
path: 'checkout',
loadComponent: () =>
loadRemoteModule('checkout', './CheckoutComponent')
.then(m => m.CheckoutComponent)
.catch(() => CheckoutFallbackComponent) // fallback defined in shell
}
// Single SPA — catch mount errors at the shell level
const parcel = mountRootParcel(checkoutConfig, { domElement })
parcel.mountPromise.catch(() => renderCheckoutFallback())
Props — pass identifiers, not domain objects (Rule 2):
{/* React — identifiers only */}
<CheckoutMicrofrontend userId={userId} cartId={cartId} />
{/* ✗ Never: user={fullUserObject} cart={fullCartObject} */}
// Angular — route param carries the identifier; remote reads ActivatedRoute itself
// ✓ { path: 'checkout/:cartId', loadComponent: () => loadRemoteModule(...) }
// ✗ resolve: { cart: CartResolver, user: UserResolver } — container owns context
// Single SPA — customProps with identifiers only
registerApplication({
name: 'checkout',
app: () => import('checkout/main'),
activeWhen: '/checkout',
customProps: { userId, cartId } // ✓ identifiers only
})
Same-page communication (horizontal split) — event emitter between peers, never shared state (Rule 4):
// MFE-to-MFE on the same page — domain events OK between peers, not in shell
eventBus.emit('catalog:filterChanged', { category: 'audio' })
// ✗ Never: import { checkoutStore } from '@org/checkout-mfe/store'
Shell platform bus — chrome only (Rules 4, 7):
// ✓ MFE requests shell-owned UI
platformBus.emit('shell:modal:open', { id: 'confirm', title: 'Continue?' })
// ✗ Shell must not own domain reactions
platformBus.on('checkout:completed', ({ orderId }) => { ... })
Cross-area navigation and data — first segment switches MFE; depth stays in MFE (Rules 4, 7):
// ✓ Any style that changes the first segment — implementation is flexible
navigate('/catalog')
// <Link to="/catalog"> or <a href="/catalog">
// ✓ Deeper path owned by catalog MFE — no shell redeploy when this route is added
navigate(`/catalog/product/${productId}`)
// ✓ Store a token; receiving MFE retrieves it independently
sessionStorage.setItem('auth_token', token)
// ✗ window.history.pushState({ user: fullUserObject }, '', '/catalog')
Quick checklist for validity questions — no file load needed.
If any answer is no, the boundary needs to be revisited before implementation begins.
Scan in this order — most impactful violations first:
references/rules-core.md for full patterns.references/routing-ownership.md).needs: coupling in pipelines.ts-arch + jest) for monorepos.For a full boundary audit: lead with violations in severity order. For each violation, name the rule, identify the specific code location, and explain the consequence in one sentence. End with a brief list of rules that are satisfied, then the highest-impact fixes in order. For single-violation reviews, inline annotation is preferable to a full report.
Inline annotation format (use during code review for individual violations):
// ✗ Rule 3 CRITICAL — direct import from another MFE's internals
// bypasses the API contract; defeats independent deployment
import { userStore } from '@org/auth-mfe/store'
Boundary note format (use after generating code with a necessary rule trade-off):
Boundary note: Rule 2 relaxed — 6 props passed per user constraint.
Consequence: the container owns more context than the micro-frontend should require.
Watch for: increasing coordination as props evolve; consider whether this boundary is in the right place.
Example 1 — shell generation
User says: "Generate the shell code to mount our CheckoutMFE using Module Federation. It needs the user ID and cart ID."
Expected: Generate shell with React.lazy dynamic import, ErrorBoundary wrapping in shell, identifiers only as props. No static import, no domain objects.
Example 2 — violation review
User says: "Review this code" + pastes shell with import { useAuthStore } from '@org/auth-mfe/store'
Expected: Flag Rule 3 Critical violation. Explain alias does not fix coupling. Recommend sessionStorage or InjectionToken pattern.
Example 3 — new project User says: "Help me create a micro-frontend for the loyalty points feature." Expected: Trigger cold start. Ask team ownership first. Do not generate code until all three checks resolved.
No framework context provided
User pastes code with no identifiable toolchain (no ModuleFederationPlugin, no loadRemoteModule, no registerApplication).
Action: Apply rules at the principle level using framework-agnostic patterns. Ask one question: "Which toolchain are you using — Module Federation, Native Federation, or Single SPA?" before generating toolchain-specific code.
Boundary fails multiple rules simultaneously
User code violates Rules 2, 3, and 4 at once (too many props, cross-boundary import, and shared store).
Action: Report Critical violations first (Rules 3 and 4), then High (Rule 2). Do not bundle into a single issue. Each violation has a distinct root cause and fix. Load references/remediation.md.
User asks for a decision requiring team context User asks "how many MFEs should we have?" or "is this the right boundary?" without team information. Action: Do not give a number or validate the boundary. Ask the team ownership and domain question from Check 1 and Check 2 first. The answer depends entirely on team structure, not on the code.