@xema-platform/plugin-registry-web
v0.1.0
Published
Frontend-host plugin registry for the Xema platform. Exposes the plugin contribution shape (FrontendPlugin, FrontendPluginFactory), the singleton runtime registry, the HostBridge contract for host-agnostic navigation/auth/toast access, and the <PluginSlot
Maintainers
Readme
@xema-platform/plugin-registry-web
Frontend-host plugin registry for the Xema platform. Exposes the plugin contribution shape, the singleton runtime registry, the HostBridge contract for host-agnostic navigation/auth/toast access, and the <PluginSlot> rendering primitive.
This package is shell-agnostic: the same plugin code runs in a Vite SPA host (via @xema-platform/plugin-host-react-router), a Next.js host (via @xema-dev/plugin-host-nextjs), or any other React shell that supplies a HostBridge implementation.
Install
npm install @xema-platform/plugin-registry-web
# or
pnpm add @xema-platform/plugin-registry-webreact and @tanstack/react-query are peer dependencies — the host provides them.
Concepts
┌─────────────────────────────────────────────────────────────┐
│ PLUGIN AUTHOR │
│ default-exports a FrontendPluginFactory │
│ (bridge: HostBridge) => FrontendPlugin │
│ │
│ Inside plugin components: │
│ const bridge = useHostBridge(); │
│ bridge.navigation.push(path); │
│ bridge.auth.getActorToken(); │
│ bridge.toast.success(msg); │
│ ↑ no react-router, no next/navigation, no auth lib │
│ │
└─────────────────────────────────────────────────────────────┘
│
│ registered at host bootstrap
▼
┌─────────────────────────────────────────────────────────────┐
│ HOST │
│ 1. Mounts <HostBridgeContext.Provider value={bridge}> │
│ 2. Calls registerFrontendPlugin(factory, bridge) │
│ 3. Reads pluginRegistry.list() at render time │
│ - merges navItems into its sidebar │
│ - mounts routes from plugin.routes │
│ - <PluginSlot name="…"/> renders contributed panels │
└─────────────────────────────────────────────────────────────┘Quick start (any host)
import {
HostBridgeContext,
registerFrontendPlugin,
PluginSlot,
type HostBridge,
} from '@xema-platform/plugin-registry-web';
import myPluginFactory from '@xema-dev/software-dev-web';
const bridge: HostBridge = { /* host-specific implementation */ };
registerFrontendPlugin(myPluginFactory, bridge);
function App() {
return (
<HostBridgeContext.Provider value={bridge}>
<YourLayout>
<PluginSlot name="session-actions" />
</YourLayout>
</HostBridgeContext.Provider>
);
}For most hosts, you don't write the bridge by hand — drop in the matching adapter package:
- Vite + react-router →
@xema-platform/plugin-host-react-router(<DefaultHostBridgeProvider>+mountPluginRoutes). - Next.js →
@xema-dev/plugin-host-nextjs(planned). - Custom shell → implement
HostBridgedirectly against your router/auth/toast primitives.
Authoring a plugin
// my-plugin/src/index.tsx
import {
type FrontendPlugin,
type FrontendPluginFactory,
useHostBridge,
} from '@xema-platform/plugin-registry-web';
function MyPanel() {
const bridge = useHostBridge();
return <button onClick={() => bridge.navigation.push('/elsewhere')}>Go</button>;
}
const myPlugin: FrontendPluginFactory = (bridge): FrontendPlugin => ({
id: 'my-plugin',
displayName: 'My Plugin',
navItems: [{ id: 'mine', label: 'Mine', route: 'mine', section: 'Build' }],
routes: [{ path: 'mine', element: () => <MyPage />, projectScoped: true }],
panels: [{ slot: 'session-actions', id: 'mine/panel', render: () => <MyPanel /> }],
});
export default myPlugin;Plugin components import only:
- React + React hooks.
useHostBridge()from this package.@tanstack/react-query(peer-dep).- Their own UI deps (lucide icons, plain CSS, etc.) — never the host's router/auth library.
Documentation
The full plugin authoring guide, host-adapter catalog, and platform architecture are at docs.xema.dev/plugins.
Related packages
@xema-platform/plugin-host-sdk— kernelRegistry<K, V>primitive this package builds on.@xema-platform/plugin-host-react-router— Vite/react-router host adapter.@xema-dev/software-dev-web— first-party plugin (Code, Repository, session git actions).
License
Apache-2.0.
