Skip to content
Simple promise based RPC between window and worker with TypeScript
TypeScript JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

TypeScript WebWorker RPC Build Status

This is a simple RPC utils to build a bridge between window and worker as simple way using TypeScript.


yarn add typescript-webworker-rpc


Quick start

  1. Define your RPC interface.
interface AccumulatorRPC {
  add: (value: number) => void;
  get: () => number;
  1. Create an object for server-calling and register handlers.
// Maybe in web-worker context.
let totalValue = 0;
new RPCServer<keyof AccumulatorRPC, AccumulatorRPC>(self as any)
  .on('add', value => {
    totalValue += value;
  .on('get', () => ({ result: totalValue }));
  1. Create an object for client-calling.
// Maybe in window context.
const rpc = new RPCClient<keyof AccumulatorRPC, AccumulatorRPC>(worker);

await'add', 20);
const newValue = await'get', {});


Let's write an example that communicates each endpoints with ping and pong messages.

  1. Write two interfaces for that.
// window -> worker
interface Ping {
  ping: () => void;
// worker -> window
interface Pong {
  pong: () => void;
  1. Write both of client and server using both channels.
// window.ts
const pingRPC = new rpc.RPCClient<keyof Ping, Ping>(worker);
new rpc.RPCServer<keyof Pong, Pong>(worker).on('pong', async () => {
  await'ping', {});

// worker.ts
const pongRPC = new rpc.RPCClient<keyof Pong, Pong>(self as any);
new rpc.RPCServer<keyof Ping, Ping>(self as any).on('ping', async () => {
  await'pong', {});

Of course, above example doesn't be terminated because it is the infinity recursive call.



A object to call a method to send a request to web-worker side and wait a result using Promise.


await`method-name`, parameter, transfer?);

If you send an ArrayBuffer to web-worker, you can use like this. If you can transfer the ownership of that object, please use transfer parameter like postMessage.

await`addBuffer`, buffer, [buffer]);

If you want to send multiple parameters, please use an object like this.

interface ComplexCall {
  awesome: (args: { some: number; thing: string }) => void;
await`awesome`, { some: 10, thing: 'good' });


call method uses a promise to wait its result from web-worker. But if you want to post a message and don't need to wait for its result, you can use post method like this.`addBuffer`, buffer, [buffer]);

It can reduce meaningless waiting costs when you can fire and forget.


If you want to handle an error from worker, please chain error handler using onError method.

rpc.onError(error => console.error);


A object to receive a request from window and response a result.

on (for call)

You can write a method call handler like event handler.

rpc.on(`method-name`, `handler => {result, transfer}`, `transfer`);

If your method is a void function, you can write a void handler. But in other cases, a return type should be {result: ReturnType; transfer?: Transferable[] } because it should support transfer like postMessage.

on (for post)

If your handler doesn't need to response due to call from post function, you should use noReturn option when installing a method handler.

  buffer => {
  { noReturn: true },

Then there is no postMessage for that.


It is same as RPCClient#onError. If you want to handle an error from worker, please chain error handler using onError method.

rpc.onError(error => console.error);



You can’t perform that action at this time.