The BroadcastChannel API allows multiple browser tabs, windows, or iframes from the same origin to communicate with each other directly β no server, no storage polling, and no WebSocket needed.
π‘ What it does
Imagine you have your app open in two tabs:
- When you log out in one tab, the other should also log out.
- When you update a theme, all tabs should update together.
BroadcastChannel gives you a simple way to broadcast messages between all open contexts on the same origin.
βοΈ Basic usage
// Create a new channel (same name must be used everywhere)
const channel = new BroadcastChannel("app-channel");
// Send a message
channel.postMessage({ type: "LOGOUT" });
// Receive messages
channel.onmessage = (event) => {
console.log("Message from another tab:", event.data);
};
// Close the channel when done
channel.close();
β Works between:
- Browser tabs
-
Windows (opened with
window.open) - Iframes on the same origin
- Web Workers
π§ Mental Model
Think of it like a walkie-talkie channel:
- Everyone listening to
"app-channel"hears all messages. - Anyone can speak (broadcast).
- Messages donβt persist β if a tab is closed, it stops listening.
π§© Real-world examples
1. Multi-tab logout sync
// auth.js
const authChannel = new BroadcastChannel("auth");
export function logout() {
localStorage.removeItem("token");
authChannel.postMessage({ type: "LOGOUT" });
window.location.reload();
}
// elsewhere
authChannel.onmessage = (event) => {
if (event.data.type === "LOGOUT") {
window.location.reload();
}
};
β Log out in one tab β all other tabs instantly reload.
2. Sync dark/light theme across tabs
const themeChannel = new BroadcastChannel("theme");
function setTheme(theme) {
document.documentElement.dataset.theme = theme;
localStorage.setItem("theme", theme);
themeChannel.postMessage({ theme });
}
themeChannel.onmessage = (event) => {
document.documentElement.dataset.theme = event.data.theme;
};
β Change theme in one tab β others switch immediately.
β‘ Performance and limits
- Messages are asynchronous, delivered via the event loop.
- Messages are cloned (structured clone algorithm) β you can send objects, arrays, etc.
- Works only on same-origin contexts.
- Not persisted: if you reload, old messages are gone.
- Doesnβt cross browser profiles or incognito sessions.
π§° Compared to alternatives
| Use Case | Recommended |
|---|---|
| Simple tab-to-tab communication | β BroadcastChannel |
| Storage sync (with state persistence) |
localStorage event |
| Cross-origin communication | postMessage |
| Real-time server β client | WebSocket / SSE |
| Multi-tab shared worker |
SharedWorker or Service Worker
|
π§± Using in React (example)
import { useEffect } from "react";
export default function ThemeSync() {
useEffect(() => {
const channel = new BroadcastChannel("theme");
channel.onmessage = (event) => {
document.documentElement.dataset.theme = event.data.theme;
};
return () => channel.close();
}, []);
const setTheme = (theme: "light" | "dark") => {
document.documentElement.dataset.theme = theme;
localStorage.setItem("theme", theme);
new BroadcastChannel("theme").postMessage({ theme });
};
return (
<div>
<button onClick={() => setTheme("light")}>Light</button>
<button onClick={() => setTheme("dark")}>Dark</button>
</div>
);
}
π§ͺ Browser support
β
Chrome, Firefox, Edge, Safari (modern versions).
β Not supported in IE.
Fallback: use localStorageβs storage event or a Service Worker.
π§© Clean-up tips
- Always call
channel.close()when your component unmounts. - Avoid creating new channels repeatedly (reuse one per module when possible).
- In SSR frameworks like Next.js, guard it with
if (typeof window !== "undefined").
β Summary
| Feature | Description |
|---|---|
| What | Send messages between tabs/windows of the same origin |
| Persistent? | β No |
| Direction | Broadcast (one-to-many) |
| Speed | Instant (same event loop tick) |
| Use cases | Multi-tab sync (logout, theme, notifications) |
β¨ BroadcastChannel = simple, fast, native multi-tab messaging β no servers, no hacks.
Originally published on Bitlyst.
Top comments (0)