For AI agents: the complete documentation index is available at https://mfdoctor.kevinbeier.com/1.0.0/llms.txt, the full documentation bundle is available at https://mfdoctor.kevinbeier.com/1.0.0/llms-full.txt, and this page is available as Markdown at https://mfdoctor.kevinbeier.com/1.0.0/capabilities.md.

Capability matrix

Analysis depth per supported bundler. For supported / partial / unsupported product cells (Node, package managers, report surfaces), see the compatibility matrix.

CapabilityVite / Rolldown / Vite PlusRspackRsbuildWebpackModern.js
Explicit MF configYesYesYesYesYes
Static importsYesYesYesYesYes
Supported dynamic patterns (see below)YesYesYesYesYes
Manifest and statsOpt-in (manifest: true); no webpack statsDefault (!== false)Default (!== false)Default (!== false)Default under hood; see matrix
Emitted assetsOn-disk writeBundle / closeBundle (Rolldown-safe)Compilation hooksRspack when availableCompilation hooksVia Rspack/Webpack afterEmit
Opt-in runtime tracesCorrelated when runtimeTrace / mfdoctor runtime is suppliedSameSameSameSame
Cross-project checksYesYesYesYesYes
Lifecycle recordingbundler.lifecycle (vite / rolldown-vite / vite-plus)

Rules consult recorded capabilities. Missing optional input creates doctor/partial-analysis instead of pretending full analysis happened. The “Manifest and stats” row is not a blanket Yes: Vite/Rolldown omit mf-manifest.json / mf-stats.json unless manifest: true, and missing webpack compilation stats on those bundlers is expected. See the per-bundler matrix. Adapters must not scrape private Module Federation plugin fields to invent coverage — see permanent guarantees / non-goals.

Dynamic-import completeness (v1)

MFDoctor’s import/shared analysis is not “static only.” Offline check / adapter runs resolve the patterns below when evidence exists in source, config, manifest facts, or an opt-in Observability export. Unresolvable dynamics yield doctor/partial-analysis rather than fabricated certainty. MFDoctor still does not claim 100% of arbitrary runtime JavaScript.

Supported (resolved when evidence exists)

PatternEvidence
Static import / export … fromSource scan
Dynamic import("…") / import('…') of local modules, packages, or remoteAlias/exposeSource scan + configured remotes
require("…") string literalsSource scan
loadRemote("alias/expose")Source scan (recorded under imports.remotes)
loadShare("pkg") / loadShareSync("pkg")Source scan (imports.packages / dynamicPackages)
registerRemotes([{ name: "…", … }]) with string name / aliasSource scan
Conditional / runtime remotes named in an opt-in Observability traceruntimeTrace on MFDoctor options or mfdoctor runtime
Remotes listed on an on-disk mf-manifest.jsonManifest facts (imports.remotes, evidenceSources: manifest)

Shared usage for shared/unused includes static imports, resolved dynamic / loadShare* literals, and packages named in an opt-in runtime trace. Remote aliases are not treated as shared packages.

Not resolved (honest partial analysis)

PatternBehavior
import(expr), template literals, or non-literal loadRemote / loadShare*Recorded in imports.unresolvedDynamic; doctor/partial-analysis
registerRemotes(variable) or objects without string name/aliasSame
Arbitrary conditional remotes with no config, manifest, or trace evidenceNot invented; stay silent or partial when unresolved call sites exist
Executing remote JS or fetching live remotes during check / federationOut of scope (use probe / Observability separately)

When unresolved package-capable dynamics exist, shared/unused does not claim a package is unused — prefer doctor/partial-analysis over a false pass or false unused finding.