tabs-broadcast
Send events between the open tabs of your web app, and let exactly one of them do the work that must not run twice. A tiny TypeScript library over the BroadcastChannel API.
MIT Zero dependencies TypeScript, Nuxt module
Open the demo in two or three tabs to see messages travel between them and the primary tab move when you close it. Using Nuxt? Install tabs-broadcast-nuxt instead.
Messages between tabs
Publish an event in one tab and every other open tab of the same site receives it, over the browser's BroadcastChannel API. No server, no polling.
One primary tab
Exactly one tab is elected primary through the Web Locks API, with a localStorage fallback. Close it and another tab takes over, so syncing or polling runs once, not per tab.
Typed events and layers
Pass an event map as a generic for autocomplete and payload checks. Layers split one channel into independent streams, which suits micro-frontends.
- 01
Install the package
npm install tabs-broadcast (or pnpm, yarn, bun). For Nuxt 3 or 4, install the tabs-broadcast-nuxt module instead: it adds a client plugin and a useTabsBroadcast() composable.
- 02
Create the bus
new TabsBroadcast() in your app. It is a singleton: creating it again returns the same instance, and destroy() tears it down.
- 03
Subscribe in every tab
bus.on(type, callback) registers a listener. once() fires a single time, onList() registers many, and the "*" wildcard catches every event in a layer.
- 04
Emit from the primary tab
bus.emit(type, payload) sends to all tabs. By default only the primary tab may emit, so check bus.primary first or set emitByPrimaryOnly to false.
import TabsBroadcast from 'tabs-broadcast'
const bus = new TabsBroadcast()
// Subscribe in every tab
bus.on('cart:update', ({ payload }) => {
console.log('cart changed:', payload)
})
// Publish: only the primary tab emits by default
if (bus.primary)
bus.emit('cart:update', { items: 3 })- Is tabs-broadcast free?
- Yes. It is open source under the MIT licence, has zero dependencies and ships ESM and UMD builds with TypeScript types.
- Which browsers does it support?
- Every modern browser with BroadcastChannel: Chrome, Edge, Firefox and Safari 15.4 or newer. It is safe to import during SSR: without a window it does nothing.
- Why elect a primary tab?
- So that work which must not run in duplicate, such as server sync, background polling or notifications, runs in one tab only. When that tab closes or reloads, another one is promoted automatically.
- Is the channel private?
- No. BroadcastChannel is same-origin, but any script on that origin can post to it if it knows the name. Treat every payload as untrusted input and use a hard-to-guess channelName.