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-sync
User 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