Login in one tab, every tab knows. Instantly.
Cross-tab state sync via BroadcastChannel. Auth tokens, theme preferences, cart state — any value you sync is instantly available in every open tab.
Built-in helpers for the two most common cases: auth and theme. One-liners.
Leader election included. Know which tab is in charge — run background jobs, hold WebSocket connections, or send analytics from a single tab.
import { init, syncAuth, onAuthChange } from '@lorb/tab-sync';
init();
syncAuth(token);
// Every other tab immediately receives the token.npm install @lorb/tab-syncUser logs in on Tab A — Tabs B, C, D update without a page refresh. User logs out — every tab redirects to login.
import { init, syncAuth, onAuthChange } from '@lorb/tab-sync';
init();
// Tab A: user logs in
syncAuth(token);
// Tab B, C, D:
onAuthChange((token) => {
if (!token) window.location.href = '/login';
});import { init, syncTheme, onThemeChange } from '@lorb/tab-sync';
init();
syncTheme('dark');
onThemeChange((mode) => {
document.documentElement.dataset.theme = mode;
});import { init, sync, on, get } from '@lorb/tab-sync';
init();
sync('cart', { items: 3, total: 49.99 });
on('cart', (value) => updateCartBadge(value.items));
// Read the last synced value without waiting for a change
const cart = get('cart');import { init, on } from '@lorb/tab-sync';
init();
on('*', (message) => {
console.log(message.key, message.value, message.tabId);
});Leader election happens automatically. The oldest tab becomes leader.
import { init, isLeader, onLeaderChange } from '@lorb/tab-sync';
init();
if (isLeader()) {
startWebSocketConnection();
}
onLeaderChange((amLeader) => {
if (amLeader) startWebSocketConnection();
else stopWebSocketConnection();
});import { tabCount } from '@lorb/tab-sync';
console.log(`${tabCount()} tabs open`);| Export | Description |
|---|---|
init() |
Start syncing. Returns cleanup() function |
sync(key, value) |
Broadcast a value to all tabs |
on(key, callback) |
Listen for changes. Use '*' for all keys |
get(key) |
Get the last synced value |
syncAuth(token) / onAuthChange(cb) |
Auth shorthand |
syncTheme(mode) / onThemeChange(cb) |
Theme shorthand |
tabCount() |
Number of active tabs |
isLeader() |
Whether this tab is the elected leader |
onLeaderChange(cb) |
Leader election events |
destroy() |
Teardown |
SSR-safe. No-op when BroadcastChannel is unavailable.
𖦹 MIT — Lorb.studio