Stop Writing postMessage Manually For Workers — I Built a Decorator for That

Published: (March 28, 2026 at 03:18 PM EDT)
2 min read
Source: Dev.to

Source: Dev.to

Cover image for Stop Writing postMessage Manually For Workers — I Built a Decorator for That

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 rxjs
  • GitHub:
  • npm:
  • Demo:

Feedback is welcome, especially from anyone who has dealt with SharedWorker pain before.

0 views
Back to Blog

Related posts

Read more »