Most web devs sync browser tabs using localStorage or BroadcastChannel. But what if you need instant, high-frequency data sharing between tabs — like a multiplayer editor or live data dashboard?

Turns out, you can use SharedArrayBuffer + Atomics to achieve true shared memory between tabs — like low-level multi-threading in JavaScript. It’s crazy fast and doesn't need a server.

Let’s build a blazing-fast, zero-latency cross-tab bus using shared memory.


Step 1: Enable Cross-Origin Isolation (Required)

For security, SharedArrayBuffer is only available in cross-origin isolated contexts. You’ll need to serve your site with special headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

If you're using Vite, add this to vite.config.ts:

server: {
  headers: {
    "Cross-Origin-Opener-Policy": "same-origin",
    "Cross-Origin-Embedder-Policy": "require-corp"
  }
}

Now SharedArrayBuffer is enabled.


Step 2: Create Shared Memory Buffer

Each tab will access the same memory buffer using postMessage with transferable ownership.

const sharedBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 1024);
const sharedArray = new Int32Array(sharedBuffer);

You can use this like a raw memory segment. But how do other tabs get access to the same buffer?


Step 3: Share Memory Between Tabs via window.open

Unfortunately, different tabs can’t share memory automatically — but you can pass the buffer using postMessage and the window.open() reference.

Tab A (main window):

const child = window.open("/child.html");

child.addEventListener("load", () => {
  child.postMessage(sharedBuffer, "*", [sharedBuffer]);
});

Tab B (child window):

window.addEventListener("message", (e) => {
  const shared = new Int32Array(e.data);
  startWatching(shared);
});

You now have shared memory between tabs.


Step 4: Use Atomics to Sync Writes

Use Atomics to coordinate read/write access and notify changes:

// Writer (in Tab A)
Atomics.store(sharedArray, 0, Date.now()); // write a timestamp
Atomics.notify(sharedArray, 0); // notify any listener
// Reader (in Tab B)
function startWatching(shared) {
  function waitLoop() {
    Atomics.wait(shared, 0, 0); // wait until value changes
    const timestamp = Atomics.load(shared, 0);
    console.log("New data received:", new Date(timestamp));
    waitLoop();
  }
  waitLoop();
}

This loop blocks (in a worker or idle time) until a change is written. It's fast — and zero-polling.


Step 5: Add a Messaging Protocol

You can extend the buffer to hold structured messages — like IDs, types, or payloads.

// Convention:
// Index 0: change flag
// Index 1: message type
// Index 2..: payload

// Writer
Atomics.store(sharedArray, 1, 42); // message type
Atomics.store(sharedArray, 2, 1234); // payload
Atomics.store(sharedArray, 0, 1); // signal change
Atomics.notify(sharedArray, 0);

You now have a structured event bus shared between browser tabs — no server or DB required.


Pros:

  • ⚡ Blazing-fast memory sharing across tabs
  • 🧠 Enables real-time collaboration or analytics dashboards
  • 📴 Works completely offline
  • 🔍 No need for localStorage, IndexedDB, or BroadcastChannel
  • 🧵 True concurrent memory management via Atomics

⚠️ Cons:

  • 🚫 Requires cross-origin isolation (not supported everywhere)
  • 🔐 Can’t share memory unless one tab opened the other
  • 🧪 Debugging shared memory is non-trivial
  • 🧠 Only supports low-level numeric types (use structured memory carefully)

Summary

With SharedArrayBuffer and Atomics, the browser can now act like a mini operating system — complete with shared memory concurrency, manual locking, and realtime updates between tabs. This technique opens doors to collaborative apps, multiplayer UIs, and in-browser data engines — with zero server roundtrips.

It’s underused, extremely powerful, and just waiting to be applied to your next high-performance web tool.


Want to Dive Deeper?

If you’re interested in taking your real-time cross-tab synchronization skills to the next level, check out my premium, in-depth guide on Gumroad. It covers advanced concepts, real-world use cases, optimizations, and much more, with plenty of hands-on code examples to help you build high-performance applications.

Click here to get the advanced guide on Gumroad!


The Gumroad guide includes:

  • Advanced use cases for multiplayer games, real-time collaborative editors, and tab-to-tab remote control
  • Performance optimization techniques for large-scale applications
  • In-depth coverage of concurrency management and synchronization patterns
  • Full, production-ready code examples you can adapt to your own projects

If you're looking to master SharedArrayBuffer and Atomics for real-time web apps, this guide is the ultimate resource for you!


If this was helpful, you can also support me here: Buy Me a Coffee