Two simulated browser tabs — both subscribed to the same
BroadcastChannel('demo'). Type a message in Tab A and watch it
arrive in Tab B in real time. The sender never receives its own message.
Tab B called
channel.onmessage = (e) => … — it gets every message
Tab A sends.
Any tab, worker, or iframe on the same origin that opens a channel with the same name is part of the group. The sender never receives its own messages.
| Aspect | localStorage + storage event | BroadcastChannel |
|---|---|---|
| Sending | localStorage.setItem(key, JSON.stringify(data)) |
channel.postMessage(data) |
| Serialization | Manual — must JSON.stringify and JSON.parse |
None — structured clone handles it |
| Cleanup | Must removeItem immediately (triggers a second event) |
No side effects — just send |
| Event filtering | Must check event.key and event.newValue |
Only receives messages from the same channel name |
| Data types | Strings only | Any structured-cloneable value (objects, arrays, Date, Map…) |
| Same-tab detection | Sender receives its own events — must add a timestamp filter | Sender never receives its own messages |