September 2, 2025
· 4 min readSharedWorker: The Hidden API for Multi-Tab Real-Time Apps
SharedWorker is a lesser-known browser API that enables multiple tabs, windows, or iframes of the same origin to share a single background worker. This post dives into use cases, performance benefits, comparisons with other workers, implementation details, and browser support.

SharedWorker: The Hidden API for Multi-Tab Real-Time Apps
Every modern web developer has faced the multi-tab problem: open your chat app or dashboard in five tabs, and suddenly you’ve got five duplicate WebSocket connections, five redundant API calls, and five times the server load.
That’s wasteful, especially in real-time apps where efficiency matters.
This is where SharedWorker, a quiet but powerful browser API, comes in. It allows multiple tabs (or even iframes) from the same origin to share a single background thread — perfect for managing shared connections and state.
Why SharedWorker?
Normally, each tab is isolated. If you create a WebSocket in one tab, another tab will open its own. SharedWorker breaks this pattern by acting like a singleton background service for all pages on the same origin.
This means:
- ✅ Only one WebSocket connection is opened
- ✅ Shared state can be stored once, not duplicated
- ✅ Tabs can communicate with each other via the worker
A chat app, notification system, or analytics dashboard becomes lighter and more scalable with this approach.
How SharedWorker Works
Let’s visualize the flow of a multi-tab WebSocket system using a SharedWorker:
👉 Multiple tabs → one worker → one WebSocket → shared messaging.
Use Cases
SharedWorker shines when:
-
Real-time communication
- Chat apps, notifications, collaborative editors
-
Shared connections
- One WebSocket, SSE, or WebRTC channel across all tabs
-
Cross-tab caching
- Fetch once, share results with every open tab
-
Multi-iframe apps
- Centralized event bus for embedded apps
-
Task coordination
- Distribute computations or state between contexts
💡 Tip: SharedWorker is especially useful in enterprise dashboards where users open multiple windows to monitor live data streams.
SharedWorker vs. Other Workers
Not all workers are created equal. Here’s how SharedWorker stacks up:
| Feature | DedicatedWorker | SharedWorker | ServiceWorker |
|---|---|---|---|
| Scope | One page/iframe only | All pages/frames of same origin | All pages under its registered scope |
| Lifetime | Ends with page | Ends when all clients close | Event-driven, persists in background |
| Communication | postMessage (one-to-one) |
MessagePort (multi-client) |
postMessage, fetch, push, sync |
| Access to DOM | ❌ | ❌ | ❌ |
| WebSocket support | Yes (per tab) | Yes (singleton) | ❌ |
| Network Control | Limited (per tab) | Shared across tabs | Full: intercept fetch, caching, offline |
| Best For | Heavy tab-specific computation | Multi-tab real-time coordination | Offline, caching, push notifications |
| Browser Support | Wide | Partial (~46% global) | Wide (modern browsers, HTTPS only) |
Architectural View
- DedicatedWorker: Each tab creates its own worker and manages its own resources.
- SharedWorker: All tabs share one worker → can centralize WebSocket or cache.
- ServiceWorker: One background service sits between all tabs and the network, ideal for caching and offline.
Implementation Example
In each tab (main.js):
const worker = new SharedWorker("shared.js");
worker.port.start();
worker.port.onmessage = (e) => {
console.log("From worker:", e.data);
};
worker.port.postMessage({ type: "chat", text: "Hello from Tab!" });SharedWorker script (shared.js):
let clients = [];
const socket = new WebSocket("wss://example.com/socket");
socket.addEventListener("message", (e) => {
clients.forEach(port => port.postMessage({ fromServer: e.data }));
});
onconnect = (event) => {
const port = event.ports[0];
clients.push(port);
port.start();
port.onmessage = (msg) => {
socket.send(JSON.stringify(msg.data));
};
};✅ Only one WebSocket is opened. ✅ All tabs share it seamlessly.
Enjoyed this post? Follow on LinkedIn for more engineering insights.
Performance & Security Considerations
Performance
- 🚀 Resource efficiency: One connection instead of many
- 🧠 Reduced memory/CPU load: Less duplication
- ⚡ Lower server load: Fewer sockets to maintain
Security
- 🔒 Same-origin only: All pages must match protocol, host, and port
- ❌ No DOM access: Worker is sandboxed
- 📜 Independent CSP: Worker script must include its own CSP headers
⚠️ Warning: Don’t rely on SharedWorker alone in production if Safari <16 or IE users are in your audience.
Browser Support
Browser support is limited:
- ✅ Chrome, Firefox, Edge (Chromium)
- ❌ Safari <16 (unsupported)
- ❌ IE (unsupported)
Global support: ~46%.
Fallbacks:
- BroadcastChannel API (~91% support)
localStorageevents (hacky but works)
Conclusion
SharedWorker is a scaling hack for multi-tab apps. It solves:
- Duplicate WebSocket connections
- Wasted bandwidth
- Fragmented state between tabs
Use it for real-time dashboards, chats, or collaborative tools — but be aware of Safari and legacy support issues. Always provide fallbacks like BroadcastChannel.
If you’re building a real-time browser app, SharedWorker could be the missing piece that makes your architecture leaner and smarter.