New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

elastic-worker

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

elastic-worker

Use worker as simple asynchronous function

latest
Source
npmnpm
Version
3.0.0
Version published
Weekly downloads
28
211.11%
Maintainers
1
Weekly downloads
 
Created
Source

elastic-worker

npm version npm downloads license

Table of Contents

  • Overview
  • Installation
  • Quick Start
  • registerWorker
  • ElasticWorker
  • Transfer
  • Errors
  • Benchmark
  • License

Overview

elastic-worker provides a simple and unified abstraction over Web Workers (browser) and Worker Threads (Node.js).

It enables developers to run CPU-intensive or blocking tasks in worker threads without manually handling worker setup, messaging, or lifecycle management.

This package exports:

  • registerWorker — register functions inside a worker context
  • ElasticWorker — scalable worker pool for parallel execution
  • Transfer - a class to use for passing transferable objects

Installation

npm install elastic-worker

Quick Start

Organize your project with a separated worker file:

src/
 worker.ts
 main.ts

[!NOTE]
The examples are written in TypeScript to demonstrate type usage, but you can also use JavaScript.
Both JavaScript and TypeScript examples are provided in examples.

1. Define worker functions (worker.ts)

import { registerWorker } from "elastic-worker";

const add = (a: number, b: number) => a + b;
const sub = (a: number, b: number) => a - b;

const calc = { add, sub };

export type Calculator = typeof calc;

// Register functions for worker usage
registerWorker(calc);

2. Use them from the main thread (main.ts)

import { ElasticWorker } from "elastic-worker";
import type { Calculator } from "./worker.ts";

const workerUrl = new URL("./worker.ts", import.meta.url);
const elasticWorker = new ElasticWorker<Calculator>(workerUrl);

const add = elasticWorker.func("add");
const subtract = elasticWorker.func("sub");

const addResult = await add(1, 2); // runs in worker
const subResult = await subtract(5, 3); // runs in worker

Flow at a Glance

main.ts  →  ElasticWorker  →  worker.ts (your functions)

registerWorker

Registers functions inside a worker context.

[!CAUTION]
Functions and variables defined in the worker file where registerWorker is called cannot be directly imported into the main thread. If you need a function to be used directly by both threads, define it in a separate module and import it into the worker file.

registerWorker(functionsObject);

ElasticWorker

An ElasticWorker can scale horizontally by spawning multiple workers.
It is ideal for parallel, independent tasks (e.g., CPU-bound batch jobs).

Constructor

new ElasticWorker(url, options);
  • url — URL to the worker file
  • options — configuration object (see below)

Example (ESM):

import { ElasticWorker } from "elastic-worker";

const workerUrl = new URL("./worker.ts", import.meta.url);
const elasticWorker = new ElasticWorker(workerUrl, {
  minWorkers: 2,
  maxWorkers: 4,
  maxTasks: 1000,
  idleTimeout: 1000,
});

Example (CJS):

const { ElasticWorker } = require("elastic-worker");
const { pathToFileURL } = require("url");
const path = require("path");

const workerUrl = pathToFileURL(path.resolve("./worker.js"));
const elasticWorker = new ElasticWorker(workerUrl);

Options

  • minWorkers (default: 1) — Minimum idle workers to keep alive, prevents cold starts.
  • maxWorkers (default: 2) — Maximum worker instances allowed.
  • maxTasks (default: Infinity) — Maximum tasks allow for waiting while workers are busy.
  • idleTimeout (default: 500 ms) — Time in milliseconds before an idle worker is terminated.
  • TaskStore (default: Queue) — Custom task store constructor used to store pending tasks.

TaskStore

TaskStore lets you plug in your own task store implementation. Provide a class that implement the interface TaskStore and pass it in ElasticWorker options.

Example

import { ElasticWorker } from "elastic-worker";
import type { TaskStore, Task } from "elastic-worker";

class PriorityQueue implements TaskStore {
  readonly maxSize: number;
  private readonly items: Task[] = [];

  constructor(maxSize: number = Infinity) {
    this.maxSize = maxSize;
  }

  get count() {
    return this.items.length;
  }

  push(item: Task) {
    this.items.push(item);
    this.items.sort((a, b) => a.timeout - b.timeout);
  }

  pull() {
    return this.items.shift();
  }

  all() {
    return this.items.values();
  }

  clear() {
    this.items.length = 0;
  }
}

const workerUrl = new URL("./worker.ts", import.meta.url);
const elasticWorker = new ElasticWorker(workerUrl, {
  TaskStore: PriorityQueue,
});

Properties

  • pool (read-only) — Current worker pool.
  • taskStore (read-only) — task store.

Methods

func

Creates a callable wrapper around a worker function.

const controller = new AbortController();

const add = elasticWorker.func("add", {
  timeoutMs: 10000,
  signal: controller.signal,
});

Parameters:

  • funcName — Registered worker function name
  • options:
    • timeoutMs (default: 5000) — Call timeout
    • signalAbortSignal for cancellation

terminate

Gracefully terminates all workers and clears the task store.
Use this if you’re finished with the worker pool.

await elasticWorker.terminate();

Transfer

The Transfer class provides a clean way to send Transferable Objects between threads. Instead of passing a separate transfer list as a second parameter (like in postMessage), Transfer wraps both your data and its transferable references in a single object—keeping worker function signatures simple and consistent.

[!NOTE] You don't need to use Transfer unless you are trying to transfer large data to worker thread.

Usage

  • To send a Transferable Object back from the worker, return a Transfer object with Transferable Object inside.
  • Access the wrapped data via the value property of the Transfer instance.

Rules

  • All parameters must be wrapped inside a Transfer object.
  • A worker function can accept only one parameter, and it must be a Transfer instance.

Example

main.ts

const processLargeData = elasticWorker.func("processLargeData");

const largeData = new ArrayBuffer(8);
const t = new Transfer(largeData, [largeData]);

const result = await processLargeData(t);
console.log("result", result.value);

worker.ts

const processLargeData = (t: Transfer) => {
  const largeData = t.value;
  return new Transfer(largeData, [largeData]);
};

registerWorker({ processLargeData });

Constructor

The Transfer constructor takes two parameters:

  • value — Any data you want to send (can include Transferable objects).
  • transferList — An array of Transferable objects that should be transferred, similar to the second argument in postMessage.
const buffer1 = new ArrayBuffer(8);
const buffer2 = new ArrayBuffer(16);

const transfer = new Transfer(
  { buffer1, buffer2, num: 1, str: "hello world" },
  [buffer1, buffer2]
);

Properties

  • value — The data being transferred between the main and worker threads.

Errors

  • TimeoutError — Worker call exceeded timeout
  • TaskOverflowErrormaxTasks limit reached
  • AbortedError — Worker call was cancelled
  • WorkerTerminatedError — Worker was terminated
  • FunctionNotFoundError — Function not registered in worker

Benchmark: Main Thread vs ElasticWorker (Fibonacci Example)


Main thread:              596.17 ms
Elastic worker(4 worker): 156.19 ms (~3.82 x faster)

The benchmark results can vary significantly based on the number of worker threads (maxWorker) and the computational intensity of the task.

  • For CPU-intensive tasks (like Fibonacci or large data processing), increasing maxWorker generally provides near-linear performance gains — e.g., maxWorker: 2 ≈ 2× faster, maxWorker: 4 ≈ 4× faster.
  • For lightweight or I/O-bound tasks, scaling may be less efficient — even with maxWorker: 8, the speedup might be closer to ~5× depending on how much real computation is involved.

See examples/js/benchmark.js try it yourself.

Examples

Here are javascript and typescript examples.

License

MIT

Keywords

async-worker

FAQs

Package last updated on 27 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts