
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
comlink-worker-pool
Advanced tools
Web Worker Pool library powered by Comlink to offload CPU-intensive work and parallelise them
🚀 Try the Live Playground Demo!
Effortless parallelism for your React and JS/TS apps.
A blazing-fast, ergonomic Web Worker pool library powered by Comlink. Offload CPU-intensive work to a pool of workers, maximize throughput, and keep your UI smooth.
Install from your monorepo root:
bun add comlink-worker-pool
Or with npm:
npm install comlink-worker-pool
Import and use the worker pool in your app:
import { WorkerPool } from "comlink-worker-pool";
import * as Comlink from "comlink"; // or your Comlink import
// Define your worker API interface
type WorkerApi = {
fibAsync(n: number): Promise<number>;
};
// Create the worker pool
const pool = new WorkerPool<
{ method: string; args: unknown[] }, // Task type
unknown, // Result type (can be more specific)
WorkerApi // Proxy type
>({
size: 2,
workerFactory: () =>
new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
proxyFactory: (worker) => Comlink.wrap<WorkerApi>(worker),
onUpdateStats: (stats) => console.log("Pool stats:", stats),
workerIdleTimeoutMs: 30000, // Optional: terminate idle workers after 30s
maxTasksPerWorker: 100, // Optional: terminate workers after 100 tasks
maxWorkerLifetimeMs: 5 * 60 * 1000, // Optional: terminate workers after 5 minutes
});
// Use the API proxy for ergonomic calls
const api = pool.getApi();
const result = await api.fibAsync(10);
console.log(result); // Output: 55
// Get live pool stats
console.log(pool.getStats());
Option | Type | Description |
---|---|---|
size | number | Number of workers in the pool |
workerFactory | () => Worker | Factory function to create new workers |
proxyFactory | (worker: Worker) => P | Factory to wrap a worker with Comlink or similar |
onUpdateStats | (stats: WorkerPoolStats) => void | Callback on pool stats update (optional) |
workerIdleTimeoutMs | number | Idle timeout for terminating workers (optional) |
maxTasksPerWorker | number | Max tasks per worker before termination (optional) |
maxWorkerLifetimeMs | number | Max worker lifetime in milliseconds (optional) |
maxConcurrentTasksPerWorker | number | Max concurrent tasks per worker (optional, defaults to 1) |
WorkerPool<T, R, P>
T
: Task type (must be { method: string; args: unknown[] }
for proxy mode)R
: Result typeP
: Proxy type (your worker API interface)The WorkerPool supports automatic worker termination based on different criteria to prevent memory leaks and ensure optimal performance:
maxTasksPerWorker
)const pool = new WorkerPool<WorkerApi>({
// ... other options
maxTasksPerWorker: 100, // Terminate workers after 100 tasks
});
maxWorkerLifetimeMs
)const pool = new WorkerPool<WorkerApi>({
// ... other options
maxWorkerLifetimeMs: 5 * 60 * 1000, // Terminate workers after 5 minutes
});
workerIdleTimeoutMs
)const pool = new WorkerPool<WorkerApi>({
// ... other options
workerIdleTimeoutMs: 30 * 1000, // Terminate idle workers after 30 seconds
});
All lifecycle management options can be combined for comprehensive worker management.
By default, each worker processes tasks sequentially (one at a time). However, you can configure workers to handle multiple tasks concurrently, which is especially beneficial for I/O-bound operations or tasks that involve waiting.
const pool = new WorkerPool<WorkerApi>({
size: 2,
maxConcurrentTasksPerWorker: 3, // Allow up to 3 concurrent tasks per worker
workerFactory: () => new Worker(new URL("./worker.ts", import.meta.url)),
proxyFactory: (worker) => Comlink.wrap<WorkerApi>(worker),
});
// These 6 tasks will run on 2 workers, with up to 3 tasks per worker concurrently
const results = await Promise.all([
api.fetchData("url1"), // Worker 1, Task 1
api.fetchData("url2"), // Worker 1, Task 2
api.fetchData("url3"), // Worker 1, Task 3
api.fetchData("url4"), // Worker 2, Task 1
api.fetchData("url5"), // Worker 2, Task 2
api.fetchData("url6"), // Worker 2, Task 3
]);
✅ Good for:
❌ Avoid for:
// For I/O-bound tasks: Higher concurrency can improve throughput
const ioPool = new WorkerPool<ApiWorker>({
size: 2,
maxConcurrentTasksPerWorker: 10, // High concurrency for I/O
// ...
});
// For CPU-bound tasks: Use more workers instead of concurrency
const cpuPool = new WorkerPool<ComputeWorker>({
size: navigator.hardwareConcurrency || 4, // More workers
maxConcurrentTasksPerWorker: 1, // Sequential processing (default)
// ...
});
When using concurrent execution, the pool statistics include additional information:
const stats = pool.getStats();
console.log({
runningTasks: stats.runningTasks, // Total tasks currently executing
availableForConcurrency: stats.availableForConcurrency, // Workers that can accept more tasks
// ... other existing stats
});
// worker.ts
export function fibAsync(n: number): number {
return n <= 1 ? n : fibAsync(n - 1) + fibAsync(n - 2);
}
getApi(): P
— Returns a proxy for calling worker methods as if local (recommended).getStats(): WorkerPoolStats
— Returns live stats about the pool.terminateAll(): void
— Terminates all workers and clears the pool.interface WorkerPoolStats {
size: number; // Configured maximum number of workers
available: number; // Workers available to take new tasks
queue: number; // Tasks waiting in the queue
workers: number; // Currently instantiated workers
idleWorkers: number; // Workers with no running tasks
runningTasks: number; // Total tasks currently executing
availableForConcurrency: number; // Workers that can accept additional concurrent tasks
}
Key differences with concurrent execution:
idleWorkers
: Workers with zero running tasksrunningTasks
: Total count of all executing tasks across all workersavailableForConcurrency
: Workers that haven't reached their maxConcurrentTasksPerWorker
limitbun run --filter comlink-worker-pool build
bun run --filter comlink-worker-pool test
Try the live playground demo here: https://natanelia.github.io/comlink-worker-pool/
If you want to run it locally, see the playground README.
Issues and PRs are welcome! Please open an issue or submit a pull request on the GitHub repository.
MIT
See the global README for overall monorepo setup and structure.
See the global README for monorepo setup and structure.
FAQs
Web Worker Pool library powered by Comlink to offload CPU-intensive work and parallelise them
The npm package comlink-worker-pool receives a total of 660 weekly downloads. As such, comlink-worker-pool popularity was classified as not popular.
We found that comlink-worker-pool demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.