<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny" -->

---
title: Stop using the localStorage hack to sync browser tabs....
description: The BroadcastChannel API is a native browser solution for syncing state across tabs, workers, and iframes on the same origin — replacing the common...
canonical: https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively. | daily.dev
og:description: The BroadcastChannel API is a native browser solution for syncing state across tabs, workers, and iframes on the same origin — replacing the common...
og:url: https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny
og:image: https://api.daily.dev/og/posts/ozaqoxhNy.png
og:image:alt: Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively.
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively.

**[DEV](https://daily.dev/sources/devto)** · 5 min read · 76 upvotes · 5 comments

## Summary

The BroadcastChannel API is a native browser solution for syncing state across tabs, workers, and iframes on the same origin — replacing the common localStorage hack. The localStorage pattern requires writing a sentinel value, listening for storage events, filtering noise from the cleanup removeItem call, and manually JSON-serializing data. BroadcastChannel replaces all of that with a simple postMessage/onmessage interface that supports structured clone (no JSON roundtrip needed). Practical use cases include logout propagation, cart sync, and live config refresh. The API is Baseline 2022, supported in Chrome 54+, Firefox 38+, and Safari 15.4+, and works in Web Workers and Service Workers as well as the main thread.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://dev.to/parsajiravand/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively-4an9>

## Questions this post answers

### How do I sync state or send messages between browser tabs on the same origin?

Use the BroadcastChannel API: create a channel with `new BroadcastChannel('name')` in each tab, then call `channel.postMessage(data)` to send and set `channel.onmessage` to receive. It uses the structured clone algorithm, so objects, arrays, Date, Map, Set, ArrayBuffer, and Blob can be sent directly without JSON serialization, and the sender never receives its own messages.

_Anyone wiring up cross-tab sync can compare BroadcastChannel tradeoffs and patterns via daily.dev._

### What browsers support the BroadcastChannel API?

BroadcastChannel is Baseline 2022 and supported in all currently maintained browsers: Chrome since version 54 (2016), Firefox since version 38 (2015), and Safari since version 15.4 (March 2022). It also works inside Web Workers and Service Workers, not just the main document thread.

_Checking browser support before adopting an API is easier when tracking web platform changes on daily.dev._

### Why is using localStorage with a storage event listener for cross-tab messaging considered a bad pattern?

It repurposes a persistence API as a messaging side-channel: every message requires writing a sentinel value, immediately calling removeItem to clean up, filtering out the extra storage event that removeItem itself triggers, adding a timestamp to avoid deduplication issues, and JSON stringifying and parsing because storage only holds strings. BroadcastChannel replaces this whole workaround with a single postMessage call and typed payloads, and is also much easier for lint tooling to reason about since the message is one call rather than two correlated statements.

_Developers refactoring away from storage-event hacks can track cleaner API patterns like this on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@taiwofrancis** · 3 upvotes

> BroadcastChannel is one of those APIs you forget exists until you need it. 😂

**@allinonetools** · 3 upvotes

> I’ve used the localStorage approach before, and it always felt a bit hacky. BroadcastChannel is much cleaner and makes cross-tab syncing feel like what it should’ve been.

**@oleksandrbuzunov** · 1 upvotes

> will it sync across nodes?

**@agustinbarrientos** · 0 upvotes

> The app shell should close the BroadcastChannel during cleanup. Hot reload can leave two listeners handling the same event

## Similar posts on daily.dev

- [Local-first browser data gets real](https://daily.dev/posts/local-first-browser-data-gets-real-3peuc7cfi) · InfoWorld · 1 upvotes · 0 comments
- [Chrome for Developers](https://daily.dev/posts/chrome-for-developers-omnbeutcy) · Chrome Developers · 57 upvotes · 4 comments
- [Offline-first frontend apps in 2025: IndexedDB and SQLite in the browser and beyond](https://daily.dev/posts/offline-first-frontend-apps-in-2025-indexeddb-and-sqlite-in-the-browser-and-beyond-djyieqljy) · LogRocket · 1 upvotes · 0 comments

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#javascript](https://daily.dev/tags/javascript), [#frontend](https://daily.dev/tags/frontend)

[View this post on daily.dev](https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively.","url":"https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny"},"datePublished":"2026-08-10T03:53:56.974Z","dateModified":"2026-09-13T21:33:39.452Z","description":"The BroadcastChannel API is a native browser solution for syncing state across tabs, workers, and iframes on the same origin — replacing the common...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/69c743e539ec2ee3e0cee3a1c76cbeb2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/69c743e539ec2ee3e0cee3a1c76cbeb2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"DEV","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"DEV","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/devto","url":"https://daily.dev/sources/devto"},"commentCount":5,"discussionUrl":"https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":76},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":5}],"keywords":"webdev,javascript,frontend","timeRequired":"PT5M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"DEV","item":"https://daily.dev/sources/devto"},{"@type":"ListItem","position":3,"name":"Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively."}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny","comment":[{"@type":"Comment","text":"BroadcastChannel is one of those APIs you forget exists until you need it. 😂","datePublished":"2026-08-12T10:57:04.443Z","dateModified":"2026-08-12T10:57:59.733Z","url":"https://daily.dev/posts/ozaqoxhNy#c-gwI5sgnbw","author":{"@type":"Person","name":"Taiwo Francis Oguntade","url":"https://daily.dev/taiwofrancis","image":"https://media.daily.dev/image/upload/s--px3_Pvo4--/f_auto/v1785515368/avatars/avatar_FStpm3ZejUD3qGlEeoOUS?_a=BAMAMicg0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3}},{"@type":"Comment","text":"I’ve used the localStorage approach before, and it always felt a bit hacky. BroadcastChannel is much cleaner and makes cross-tab syncing feel like what it should’ve been.","datePublished":"2026-08-11T03:05:23.626Z","url":"https://daily.dev/posts/ozaqoxhNy#c-8Aal4Mcoc","author":{"@type":"Person","name":"AllInOneTools","url":"https://daily.dev/allinonetools","image":"https://media.daily.dev/image/upload/s--4ZT8QlF0--/f_auto/v1769790028/avatars/avatar_igzBsWloJeaegzm9bQltZ?_a=BAMAMiiu0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3}},{"@type":"Comment","text":"will it sync across nodes?","datePublished":"2026-08-14T20:21:06.497Z","url":"https://daily.dev/posts/ozaqoxhNy#c-CXxQYS1CF","author":{"@type":"Person","name":"oleksandr buzunov","url":"https://daily.dev/oleksandrbuzunov","image":"https://lh3.googleusercontent.com/a/ACg8ocKEOmoXEUdyYUCo2_TrduRrtMbZm9GMZo7Jr_zMrKhKfQl7tga9=s96-c"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}},{"@type":"Comment","text":"The app shell should close the BroadcastChannel during cleanup. Hot reload can leave two listeners handling the same event","datePublished":"2026-08-16T05:18:19.077Z","url":"https://daily.dev/posts/ozaqoxhNy#c-rNczOSKlM","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/stop-using-the-localstorage-hack-to-sync-browser-tabs-broadcastchannel-does-it-natively--ozaqoxhny#faq","mainEntity":[{"@type":"Question","name":"How do I sync state or send messages between browser tabs on the same origin?","acceptedAnswer":{"@type":"Answer","text":"Use the BroadcastChannel API: create a channel with `new BroadcastChannel('name')` in each tab, then call `channel.postMessage(data)` to send and set `channel.onmessage` to receive. It uses the structured clone algorithm, so objects, arrays, Date, Map, Set, ArrayBuffer, and Blob can be sent directly without JSON serialization, and the sender never receives its own messages. Anyone wiring up cross-tab sync can compare BroadcastChannel tradeoffs and patterns via daily.dev."}},{"@type":"Question","name":"What browsers support the BroadcastChannel API?","acceptedAnswer":{"@type":"Answer","text":"BroadcastChannel is Baseline 2022 and supported in all currently maintained browsers: Chrome since version 54 (2016), Firefox since version 38 (2015), and Safari since version 15.4 (March 2022). It also works inside Web Workers and Service Workers, not just the main document thread. Checking browser support before adopting an API is easier when tracking web platform changes on daily.dev."}},{"@type":"Question","name":"Why is using localStorage with a storage event listener for cross-tab messaging considered a bad pattern?","acceptedAnswer":{"@type":"Answer","text":"It repurposes a persistence API as a messaging side-channel: every message requires writing a sentinel value, immediately calling removeItem to clean up, filtering out the extra storage event that removeItem itself triggers, adding a timestamp to avoid deduplication issues, and JSON stringifying and parsing because storage only holds strings. BroadcastChannel replaces this whole workaround with a single postMessage call and typed payloads, and is also much easier for lint tooling to reason about since the message is one call rather than two correlated statements. Developers refactoring away from storage-event hacks can track cleaner API patterns like this on daily.dev."}}]}
```

