Broadcast Channel API
The Broadcast Channel API lets tabs, windows, iframes, and web workers on the same origin send messages to each other. It is a simple alternative to postMessage when you do not need to target a specific window — any context listening on the same channel receives the message.
Basic Usage
Create a channel and start sending messages:
const channel = new BroadcastChannel("app-state");
// Listen for messages
channel.onmessage = (event) => {
console.log("Received:", event.data);
};
// Send a message to all other contexts on this channel
channel.postMessage({ type: "user-login", userId: 12345 });
Every context that creates a BroadcastChannel("app-state") with the same name joins the same channel. Messages sent from one context reach all other contexts on that channel.
Closing a Channel
const channel = new BroadcastChannel("sync");
channel.postMessage({ type: "data-update", payload: { count: 42 } });
channel.close(); // stop receiving messages
After close(), the channel is disconnected. It cannot be reopened — create a new instance if needed.
Cross-Tab State Synchronization
Use a broadcast channel to keep multiple tabs in sync:
// In each tab
const stateChannel = new BroadcastChannel("app-state");
// Store current state
let appState = { theme: "light", sidebar: true };
// When state changes, broadcast to other tabs
function updateState(patch) {
appState = { ...appState, ...patch };
stateChannel.postMessage({
type: "state-update",
state: appState,
timestamp: Date.now()
});
}
// Receive state updates from other tabs
stateChannel.onmessage = (event) => {
if (event.data.type === "state-update") {
appState = event.data.state;
renderApp();
}
};
When the user changes theme in tab A, tab B and tab C receive the update and re-render automatically.
Communicating with Web Workers
// main.js — in the main thread
const workerChannel = new BroadcastChannel("worker-messages");
workerChannel.onmessage = (event) => {
console.log("Worker says:", event.data);
};
// Send work to the worker
const worker = new Worker("processor.js");
worker.onmessage = (event) => {
// This is standard postMessage
workerChannel.postMessage({ result: event.data });
};
// processor.js — in the worker
self.onmessage = (event) => {
// Send result back via standard postMessage
// The main thread broadcasts it to other contexts
self.postMessage({ processed: event.data.value * 2 });
};
Note: the Broadcast Channel and postMessage between main thread and workers are separate APIs. Messages from workers arrive via onmessage on the worker, not via BroadcastChannel. Use the broadcast channel to redistribute those messages to other contexts.
Message Format
Any structured-cloneable value works as the message payload:
channel.postMessage("simple string");
channel.postMessage({ key: "value", numbers: [1, 2, 3] });
channel.postMessage(new Uint8Array([0x68, 0x69])); // ArrayBuffer views
channel.postMessage(null); // works too
Comparing Communication APIs
| API | Use when |
|---|---|
BroadcastChannel | Broadcasting to all contexts on the same origin |
postMessage | Sending to a specific window or worker |
MessageChannel | Point-to-point communication between two specific contexts |
localStorage event | Reacting to storage changes across tabs |
BroadcastChannel is simpler than postMessage when you need fan-out: one message reaches everyone listening. postMessage requires keeping a reference to the target window.
Authentication State Sync Example
Keep authentication state consistent across tabs:
const authChannel = new BroadcastChannel("auth-events");
// Simulated auth check
let currentUser = null;
function login(user) {
currentUser = user;
authChannel.postMessage({
type: "login",
user: user,
at: Date.now()
});
}
function logout() {
currentUser = null;
authChannel.postMessage({
type: "logout",
at: Date.now()
});
}
// React to auth events from other tabs
authChannel.onmessage = (event) => {
const { type, user } = event.data;
if (type === "login") {
currentUser = user;
updateUI();
} else if (type === "logout") {
currentUser = null;
showLoginScreen();
}
};
When a user logs out in tab A, all other open tabs receive the broadcast and update their UI accordingly.
Limitations
Same origin only. Channels cannot communicate across origins. If you need cross-origin messaging, postMessage with a target origin is the correct tool.
No delivery confirmation. postMessage delivers asynchronously with no acknowledgment. If you need confirmation of delivery, implement a reply protocol yourself.
Browser support. BroadcastChannel is supported in all modern browsers. Internet Explorer does not support it. For IE support, use a localStorage-based fallback or a library.
See Also
- /guides/javascript-service-workers/ — background scripts that can receive broadcast messages
- /guides/javascript-websockets/ — persistent two-way server communication
- /guides/javascript-structured-clone/ — how structured clone handles complex objects for channel messaging