🚀 Try the Live Playground Demo!
The modern monorepo for high-performance, ergonomic web worker pools in React, JS, and TypeScript — powered by Comlink.
- 🚀 Effortless parallelism: Offload heavy computation to workers, keep your UI snappy
- 🧩 Modular: Use just the core, or drop in React bindings for instant hooks
- 🦾 TypeScript-first: Full type safety across packages
- 🛠️ OSS-friendly: Clean structure, easy contributions, and clear docs
- comlink-worker-pool: Reusable, Comlink-based worker pool library for parallel processing
- comlink-worker-pool-react: React bindings for the worker pool, including the
useWorkerPool
hook - playground: Interactive React demo app showcasing the worker pool and React bindings (Live playground)
Install the packages you need in your own project:
npm install comlink-worker-pool
# or for React bindings:
npm install comlink-worker-pool comlink-worker-pool-react
-
Create a worker (worker.ts):
import { expose } from "comlink"; const api = { fib: async (n: number): Promise<number> => n <= 1 ? n : (await api.fib(n - 1)) + (await api.fib(n - 2)), }; expose(api);
-
Use the WorkerPool in your app:
import { WorkerPool } from "comlink-worker-pool"; import * as Comlink from "comlink"; type WorkerApi = { fib(n: number): Promise<number>; }; const pool = new WorkerPool< { method: string; args: unknown[] }, unknown, WorkerApi >({ size: 2, maxConcurrentTasksPerWorker: 3, // NEW: Allow concurrent tasks per worker workerFactory: () => new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }), proxyFactory: (worker) => Comlink.wrap<WorkerApi>(worker), }); const api = pool.getApi(); // the following .fib calls are run in parallel const results = await Promise.all([api.fib(10), api.fib(2), api.fib(3)]); console.log(results); // Output: [55, 2, 3]
-
Create a worker (worker.ts):
import { expose } from "comlink"; const api = { add: async (a: number, b: number) => a + b, }; expose(api);
-
Use the hook in your React component:
import { useWorkerPool } from "comlink-worker-pool-react"; import { wrap } from "comlink"; type Api = { add: (a: number, b: number) => Promise<number>; }; const { api, status, result, error, call } = useWorkerPool<Api>({ workerFactory: () => new Worker(new URL("./worker", import.meta.url)), proxyFactory: (worker) => wrap<Api>(worker), poolSize: 2, }); return ( <div> <button onClick={async () => await call("add", 2, 3)}>Add 2 + 3</button> {status} {result && <div>Result: {result}</div>} {error && <div>Error: {String(error)}</div>} </div> );
See the individual package READMEs for full usage and advanced features:
If you want to contribute or run the playground locally:
- Install dependencies
bun install
- Build the worker pool library
bun run --filter comlink-worker-pool build
- Run the playground demo
bun run --filter playground dev
comlink-worker-pool/
├── packages/
│ ├── comlink-worker-pool/ # The worker pool library (core)
│ ├── comlink-worker-pool-react/ # React bindings for the worker pool
│ └── playground/ # React demo app
├── bunfig.toml
├── package.json
└── README.md
- Bun for ultra-fast builds and workspace management
- Comlink for type-safe, ergonomic worker communication
- React + Vite for a modern playground/demo
We love OSS! Issues and PRs are welcome — see the individual package READMEs for details:
Made with ❤️ by @natanelia. Licensed under the MIT License.