Skip to content

Repository files navigation

useWebWorker Logo

use-web-worker

中文 | English

React hooks for running CPU-heavy functions in Web Workers with TypeScript support, status tracking, timeout handling, and cleanup.

NPM version NPM downloads

Documentation

Quick Start

  • Function-like API - call a worker task like an async function.
  • Responsive UI - move CPU-heavy work away from the main thread.
  • TypeScript first - infer call arguments and return values from your worker function.
  • Lifecycle helpers - status, timeout, error handling, and automatic cleanup.
npm install @atom-universe/use-web-worker

Basic Usage

import { useWebWorkerFn } from '@atom-universe/use-web-worker';

function App() {
  const [workerFn, status] = useWebWorkerFn((a: number, b: number) => a + b);

  const handleClick = async () => {
    const result = await workerFn(1, 2);
    console.log(result); // 3
  };

  return (
    <div>
      <button onClick={handleClick}>Calculate</button>
      <div>Current status: {status}</div>
    </div>
  );
}

API Reference

useWebWorkerFn

Creates a generated Web Worker from a function and returns an executor.

const [workerFn, workerStatus, workerTerminate] = useWebWorkerFn(
  fn: T,
  options?: UseWebWorkerFnOptions
);

Options

interface UseWebWorkerFnOptions {
  timeout?: number;
  dependencies?: string[]; // external scripts loaded with importScripts()
  localDependencies?: ((...args: unknown[]) => unknown)[]; // helper functions stringified into the worker
  onError?: (error: Error) => void;
  onMessage?: (message: any) => void; // custom messages posted by the worker
}

Returns

  • workerFn: (...args: Parameters<T>) => Promise<ReturnType<T>> - execute the worker function.
  • workerStatus: WebWorkerStatus - current status enum value.
  • workerTerminate: (status?: WebWorkerStatus) => void - terminate the active worker and set a status.

WorkerStatusType values are exported as SUCCESS = 0, ERROR = 1, TIMEOUT = 2, RUNNING = 3, and PENDING = 4.

Progress and custom messages

The worker global scope is injected as the last argument. You do not pass it when calling workerFn.

import { useWebWorkerFn } from '@atom-universe/use-web-worker';

function compute(total: number, workerContext: Worker) {
  workerContext.postMessage(['PROGRESS', { percent: 50 }]);
  return total * 2;
}

function App() {
  const [workerFn] = useWebWorkerFn(compute, {
    onMessage: message => {
      if (message.type === 'PROGRESS') {
        console.log(message.data.percent);
      }
    },
  });

  workerFn(21);
}

useWebWorker

useWebWorker is the older direct-worker hook. Prefer useWebWorkerFn for new function-style usage.

const [data, post, terminate, worker, isRunning] = useWebWorker<Data>(
  urlOrFactoryOrWorker,
  workerOptions
);

The first argument can be a worker script URL, a () => Worker factory, or a Worker instance.

Benchmark

This repo includes a reproducible benchmark that compares a CPU workload on the main thread and in a worker thread:

pnpm benchmark

The script writes BENCHMARK.md and updates the docs data file used by the website.

Contributing

Contributions are welcome. Please feel free to submit a Pull Request.

License

MIT License

About

A React hook for easy Web Worker integration with TypeScript support.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages