@nexussdk/mfe
v0.1.0
Published
Micro-frontend singleton coordinator for Nexus SDK — prevents duplicate SDK instances across independent micro-apps sharing a page
Maintainers
Readme
@nexussdk/mfe
Micro-frontend singleton coordinator for the Nexus SDK ecosystem.
Prevents duplicate SDK instances across Module Federation remotes sharing the same page.
Zero dependencies · ~0.7 KB gzipped · Framework-agnostic.
The Problem
When you have 5 micro-apps on the same page (Module Federation, single-spa, qiankun), and each initializes the Nexus SDK:
❌ Without @nexussdk/mfe:
- 5 separate SSE connections to the flags server
- 5 separate flag caches (may diverge!)
- 5 tracker instances, potentially sending duplicate events
- 5x memory usage
✅ With @nexussdk/mfe:
- 1 coordinator (first app to initialize)
- N delegates share the coordinator's state via an in-process event bus
- Single SSE connection, single flag cache
Installation
npm install @nexussdk/mfe
# or
pnpm add @nexussdk/mfeQuick Start
Use identical code in every micro-app — roles are assigned automatically:
import { NexusMfeCoordinator } from '@nexussdk/mfe';
const coord = NexusMfeCoordinator.getInstance('my-app-id');
// First app on the page: role = 'coordinator'
// All subsequent apps: role = 'delegate'
console.log(coord.getRole());
// Subscribe to events from any app on the page
coord.subscribe('flags:update', (msg) => {
console.log('Flags updated by:', msg.sourceId);
applyFlags(msg.payload);
});
// Publish events visible to all apps
coord.publish({ type: 'tracker:event', payload: { error: 'TypeError' } });How It Works
Page loads
│
├── Shell App (loads first)
│ NexusMfeCoordinator.getInstance('shell')
│ → globalThis.__NEXUS_COORDINATOR__ is empty
│ → Becomes COORDINATOR ✅
│ → Sets globalThis.__NEXUS_COORDINATOR__ = this
│
├── Cart Remote (loads 350ms later)
│ NexusMfeCoordinator.getInstance('cart')
│ → Finds existing coordinator on globalThis
│ → Becomes DELEGATE 🔗
│ → Forwards all events to the coordinator
│
└── Checkout Remote
NexusMfeCoordinator.getInstance('checkout')
→ Becomes DELEGATE 🔗Webpack Module Federation Setup
Important: Add singleton: true to the shared config so all apps use the same instance:
// Shell app — webpack.config.js
new ModuleFederationPlugin({
name: 'shell',
remotes: { cartApp: 'cart@http://localhost:3001/remoteEntry.js' },
shared: {
'@nexussdk/mfe': { singleton: true, requiredVersion: '^0.1.0' }, // ← Required!
},
});
// Remote app — webpack.config.js
new ModuleFederationPlugin({
name: 'cart',
filename: 'remoteEntry.js',
exposes: { './Cart': './src/Cart' },
shared: {
'@nexussdk/mfe': { singleton: true, requiredVersion: '^0.1.0' }, // ← Required!
},
});Framework Examples
import { useEffect } from 'react';
import { NexusMfeCoordinator } from '@nexussdk/mfe';
export function useMfeFlags(appId: string) {
useEffect(() => {
const coord = NexusMfeCoordinator.getInstance(appId);
const handler = (msg: any) => applyFlags(msg.payload);
coord.subscribe('flags:update', handler);
return () => coord.unsubscribe('flags:update', handler);
}, [appId]);
}import { onMounted, onUnmounted } from 'vue';
import { NexusMfeCoordinator } from '@nexussdk/mfe';
export function useMfeFlags(appId: string) {
let coord: NexusMfeCoordinator;
const handler = (msg: any) => applyFlags(msg.payload);
onMounted(() => {
coord = NexusMfeCoordinator.getInstance(appId);
coord.subscribe('flags:update', handler);
});
onUnmounted(() => coord?.unsubscribe('flags:update', handler));
}import { Injectable, OnDestroy } from '@angular/core';
import { NexusMfeCoordinator } from '@nexussdk/mfe';
@Injectable({ providedIn: 'root' })
export class MfeCoordinatorService implements OnDestroy {
private coord = NexusMfeCoordinator.getInstance('angular-shell');
publish(type: string, payload: unknown) {
this.coord.publish({ type: type as any, payload });
}
subscribe(type: string, handler: (msg: any) => void) {
this.coord.subscribe(type as any, handler);
}
ngOnDestroy() {
// Only call destroy() from the shell/coordinator app
if (this.coord.getRole() === 'coordinator') this.coord.destroy();
}
}Message Types
type MfeMessageType =
| 'flags:update' // Flag state changed
| 'tracker:event' // Error/telemetry captured
| 'heartbeat' // Keep-alive
| 'coordinator:ready'; // Coordinator initialized (fires automatically)API Reference
class NexusMfeCoordinator {
static getInstance(appId: string): NexusMfeCoordinator;
getRole(): 'coordinator' | 'delegate';
getAppId(): string;
publish(message: { type: MfeMessageType; payload?: unknown }): void;
subscribe(type: MfeMessageType, listener: (msg: MfeBusMessage) => void): this;
unsubscribe(type: MfeMessageType, listener: (msg: MfeBusMessage) => void): this;
destroy(): void; // Call only from the shell/coordinator app on unmount
}License
MIT © Hồ Huỳnh Dũng
