Runtime Plugins
Runtime plugins let you change runtime behavior without changing the core runtime itself.
Use them when you need to:
- rewrite remote URLs at runtime
- customize manifest requests
- patch script loading
- override shared resolution
- add recovery or fallback behavior
- introduce new remote loading behavior
If you only need to register a plugin path in build config, see runtimePlugins. If you need the full hook list, see Runtime Hooks.
Mental model
A runtime plugin is a function that returns a ModuleFederationRuntimePlugin:
The function form matters because it lets you:
- accept options
- keep state in a closure
- reuse the same plugin logic across environments
Register a plugin
You can register runtime plugins in two places:
- Build time, through
runtimePlugins - Runtime, through
registerPlugins(...)orinstance.registerPlugins(...)
Build-time registration
Use build-time registration when the plugin should always be present for that host.
Runtime registration
Use runtime registration when the plugin depends on user state, environment, feature flags, or data fetched after startup.
Choose the right hook
Recipe: rewrite the resolved remote entry
afterResolve is the right hook when the remote has already been resolved and you want to change the final URL before loading continues.
This pattern is useful for:
- CDN indirection
- environment switching
- registry-backed routing
- domain normalization
Why this hook:
beforeRequestis earlier; the remote is not resolved yetafterResolvealready gives youremoteInfo.entry- changing
args.remoteInfo.entryhere keeps the original path, query, and hash intact
An afterResolve rewrite changes runtime loading behavior. It does not automatically rewrite the remote URL used by type generation or other build-time tooling. If you rely on generated remote types, keep that path aligned separately.
Recipe: customize manifest fetch
Use fetch when the manifest request itself needs custom behavior.
Use fetch for:
- credentials
- auth headers
- manifest retries
- custom proxy logic
If you need a ready-made transport policy, see the built-in retry plugin.
Recipe: prefer a host-owned shared dependency
resolveShare is the hook for overriding the final shared module selection.
The important part: changing args.scope or args.version alone is not enough. To change the actual winner, replace args.resolver.
Failure handling and shareStrategy
errorLoadRemote is the right place for runtime fallbacks.
One important detail: the behavior changes with shareStrategy.
version-firsteagerly loads remote entries during startup to initialize shared dependenciesloaded-firstdefers remote loading until the remote is actually used
That means:
- with
version-first, an offline remote can fail early withlifecycle: 'beforeLoadShare' - with
loaded-first, the same remote usually fails later, when code actually tries to use it
If you expect remotes to be intermittently unavailable, pair errorLoadRemote with a deliberate shareStrategy.
Version-sensitive hooks
The advanced hooks evolve over time. For common hooks like afterResolve, fetch, createScript, and loadEntry, prefer checking the installed runtime types when you depend on newer arguments or behaviors.
That is especially relevant when you rely on:
- extra script attributes in
createScript - loader hook details passed into
fetchorloadEntry - less-common lifecycle hooks used by built-in plugins