Read this before you onboard your first external plugin author. It is short, and it is the most important page in these docs.
The model#
@z0devs/* is a toolkit for shells that load trusted, curated plugins: micro-frontends authored
by your own teams or by vetted partners, onboarded through a host-controlled manifest.
Plugins run in-process. A loaded plugin executes inside the host's React tree, on the same origin,
sharing window, the singleton registries, the lifecycle event bus and — through any fetch helper you
expose — the user's session.
Treat plugin code as first-party-equivalent. The host is responsible for vetting what it loads. The library is not designed to contain malicious code, and does not claim to.
The guardrails you do get#
For known-good builds, the library gives you three real controls:
Integrity verification
An optional remoteEntryHash on the manifest entry is verified with crypto.subtle before
registerRemotes — so a swapped or tampered remoteEntry.js for a build you vetted fails closed with
integrity-violated and no retry. This is supply-chain tamper detection, not a sandbox.
Version compatibility
shellApiVersion + versionPolicy block plugins built against an incompatible host API, before their
code executes.
Curation metadata
vendor, permissions, description, icon, version are surfaced to your admin UI so a human can
review and approve an entry before it ships. The manifest endpoint is the boundary: nothing loads that
you didn't put there.
Plus a cooperation boundary between plugins: remotes receive a read + append, id-scoped
PluginRegistryApi rather than the full registry, so one plugin can't clear another's contributions or
hijack the shared event bus by accident.
A remote does get subscribe, which is deliberately not bus access — it only says "the listed set may
have changed", carries no payload, and cannot be used to emit. emit and addListener stay host-only,
which is what keeps a remote from faking another's events or watching its typed traffic.
Explicit non-goals#
These belong to a different product — running untrusted vendor code safely — and are out of scope:
| Non-goal | Why it's out of scope |
|---|---|
| Runtime sandboxing / isolation (iframe, Worker, Realms) | Plugins share the React tree by design; that's what makes the UX seamless |
| Runtime permission enforcement | permissions is reviewed by humans during curation, not enforced by a policy engine |
| Manifest signing / provenance | Host the manifest on a trusted, access-controlled endpoint instead |
| Adversarial separation between plugins | Capability scoping prevents accidents, not attacks |
The line, stated plainly
A remote sharing the JS realm can reach the raw registries through globalThis or a direct
@z0devs/mf-registry import, read the DOM, and call anything the host exposed. If you need to load
code you would not run as first-party, you need an out-of-realm boundary — iframe or worker with
postMessage — which this library does not provide. Don't load plugins you wouldn't ship yourself.
What that means in practice#
Onboarding an internal team. Fine. Same trust as a monorepo package, with independent deploys. Use version gating so a stale plugin can't take down the shell.
Onboarding a vetted partner. Workable, with process around it:
- Review the source or the build.
permissionsandproxyPrefixestell you what to look for. - Pin
remoteEntryHashper released version so their CDN can't serve different bytes later. - Serve the manifest from an authenticated endpoint; make adding an entry an audited action.
- Keep vendor credentials server-side behind a proxy route with a path allow-list, rate limits and an audit log.
- Set a CSP
script-srcthat lists partner origins explicitly.
Onboarding an open marketplace of unknown authors. Not this library. You need process isolation, and every guarantee above would be theatre.
Threats this design does address#
| Threat | Control |
|---|---|
| Tampered bundle from a vetted partner's CDN | remoteEntryHash verified pre-execution |
| Plugin built against an incompatible host API | shellApiVersion gate |
| Malformed / hand-edited manifest entry | validateManifestEntry at load, manifest-invalid telemetry |
| One plugin breaking another's contributions | Capability-scoped registries + per-remote id namespacing |
| A plugin's transient load failure taking down boot | Retry policy, error boundaries, per-plugin failure isolation |
| Vendor API secrets leaking into the browser | Server-side proxy pattern |
| A plugin loading from an origin you never approved | The manifest is the only source of remotes |
Threats it does not#
| Threat | Reality |
|---|---|
| A plugin exfiltrating session data | It shares your origin and session — nothing stops it |
| A plugin monkey-patching host internals | Same realm, same globalThis |
| A plugin reading another plugin's state | No isolation between plugins |
A malicious plugin claiming benign permissions | Metadata, not enforcement — the review step is the control |
Roadmap position#
The library's roadmap is deliberately "trusted plugins, done well": React Router v7 verified in CI,
cross-boundary HMR, adopting enhanced's automatic cross-remote DTS, and a documented 1.0 once the
API settles. A sandboxed-runtime track would be a separate product, not a patch to this one.