Stop Writing postMessage Manually For Workers — I Built a Decorator for That
Source: Dev.to

The Painful API
// Standard Worker code — just to call ONE function
const worker = new Worker('./my.worker.js');
const requestId = Math.random();
worker.postMessage({ id: requestId, command: 'processData', payload: data });
worker.onmessage = (event) => {
if (event.data.id === requestId) {
console.log(event.data.result);
}
};You need request IDs, response matching, manual routing, port management for SharedWorkers… for every single method call.
Introducing ngx‑worker‑bridge
The library removes all that boilerplate.
Define your background logic (runs in the worker thread)
import { setState } from 'ngx-worker-bridge';
export class DataModule {
private count = 0;
increment() {
this.count++;
setState('counter', this.count); // broadcasts to ALL tabs
}
async processData(payload: any) {
// heavy work here — UI thread never blocks
return expensiveOperation(payload);
}
}Call it from Angular like a normal service
import { Injectable } from '@angular/core';
import { RunInWorker, workerStore } from 'ngx-worker-bridge';
@Injectable({ providedIn: 'root' })
export class DataService {
count$ = workerStore('counter', 'shared'); // reactive, auto‑updates
@RunInWorker({ bridge: 'shared', namespace: 'data' })
increment(): Promise { return null as any; }
@RunInWorker({ namespace: 'data' })
processData(payload: any): Promise { return null as any; }
}Or from React with a hook
import { useWorkerStore } from 'ngx-worker-bridge/react';
function App() {
const count = useWorkerStore('counter', 'shared');
return service.increment()}>Count: {count};
}No postMessage. No onmessage. No request‑ID tracking. Just a decorator and a hook.
The SharedWorker Feature
SharedWorker runs once and is shared across all open browser tabs. Calling setState('counter', value) inside your module broadcasts the new value to every connected tab instantly.
Open 5 tabs — they all stay in sync, without a server or WebSockets.
Typical use‑cases:
- Notification counts
- Live stock/crypto prices
- Shared timers or sessions
- A single WebSocket connection shared across all tabs
Install
# Angular (RxJS already included)
npm i ngx-worker-bridge
# React
npm i ngx-worker-bridge rxjsLinks
- GitHub:
- npm:
- Demo:
Feedback is welcome, especially from anyone who has dealt with SharedWorker pain before.