← Blog 5 min read

SharedWorker API: One Worker Across Tabs

SharedWorker API: One Worker Across Tabs

Open the same web app in three tabs and each tab usually builds its own little world. It may create another database connection, repeat the same calculation, or fetch data that a neighboring tab already has. That independence keeps the web simple, but it can also waste memory and let tabs drift out of sync.

The SharedWorker API offers a different model. Several pages from the same origin can connect to one background JavaScript worker. The worker becomes a small coordination point: one place for shared state, expensive work, and communication that should outlive any single tab.

What the SharedWorker API changes

A regular Web Worker belongs to the page that creates it. A SharedWorker can serve multiple windows, tabs, iframes, or workers, provided they share the exact same origin. That means the protocol, hostname, and port must all match. A page on another subdomain cannot quietly join the same worker.

Each page creates a SharedWorker with the same script URL and name. The browser connects those pages to the existing worker rather than starting a separate copy. Communication happens through a MessagePort, available on the worker’s port property. The MDN SharedWorker reference documents the interface and its current compatibility.

One coordinator, several tabs

Consider a collaborative inbox open in two tabs. Without coordination, each tab might hold its own live connection and independently receive the same events. A shared worker can maintain one connection, track the latest state, and forward relevant updates to every connected page.

The pattern also works for background calculations. A finance dashboard could keep one parser or aggregation engine alive while several views request results. A large web editor could centralize access to a local index. The purpose is not merely to save a few objects. It is to create one deliberate owner for work that should be consistent across tabs.

How pages talk to a shared worker

The connection begins when a page calls new SharedWorker("worker.js"). That object exposes a port. A page can assign an onmessage handler and use postMessage() to exchange structured data with the worker. When listeners are added with addEventListener(), the port must be started explicitly with start().

Inside the worker, an onconnect handler receives each new port. The worker can store those ports in a collection, send a reply to one tab, or broadcast a state change to all of them. The MDN guide to shared workers shows the two sides of this message flow and explains the worker lifecycle.

SharedWorker is not BroadcastChannel

The two APIs can solve some of the same coordination problems, but their shapes differ. BroadcastChannel gives same-origin contexts a simple group messaging lane. Every participant can publish and listen. It does not create a shared execution environment or nominate one participant as the owner of a resource.

SharedWorker supplies that central execution context. It is useful when tabs need more than announcements: one socket, one in-memory cache, or one queue with ordered processing. For lightweight notifications, the simpler approach in our guide to the Broadcast Channel API may be enough.

Lifetime is useful but not permanent

A shared worker normally remains alive while at least one page holds a reference to it. When every connected context closes, the browser may stop the worker. Developers should not treat its memory as durable storage or assume it will survive a browser restart.

Important state belongs in a persistent store such as IndexedDB. The worker can rebuild its in-memory view when it starts again. Newer implementations may support an extendedLifetime option for short cleanup work after pages close, but that is still bounded and browser-controlled. It is not a substitute for a service worker or a server.

Security and reliability boundaries

Same-origin access is an important boundary, but applications still need a message protocol. The worker should validate message shapes, distinguish request types, and avoid treating arbitrary data as code. Its script URL must be controlled just as carefully as any other executable resource. A restrictive Content Security Policy and Trusted Types can reduce the risk of loading an unintended worker script.

Coordination also needs failure handling. Ports can disappear without a tidy farewell when a tab crashes or a device sleeps. Requests should have identifiers and timeouts. If a resource must have exactly one active owner, the locking model described in our article on the Web Locks API can complement a shared worker.

When a SharedWorker earns its place

Use a SharedWorker when several same-origin pages genuinely need one active coordinator. A shared real-time connection, cross-tab task queue, or reusable computation engine can justify the extra lifecycle and messaging code. A single-page application with no multi-tab requirement probably cannot.

The practical test is simple: name the resource that should have one owner. If that answer is vague, ordinary workers, browser storage, or BroadcastChannel will be easier to maintain. If the answer is precise, SharedWorker can turn a collection of isolated tabs into a disciplined system without merging their user interfaces or weakening the browser’s origin boundary.

Browse with more intention

Noorani brings prayer times, Qibla, tracker blocking, and privacy into one calm desktop browser built for how Muslims live online.

Download Noorani