npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mystogab/promise-pool

v3.3.1

Published

A lightweight, high-performance, and memory-efficient asynchronous pool for JavaScript and TypeScript

Readme

@mystogab/promise-pool 🚀 A lightweight, high-performance, and memory-efficient asynchronous pool for JavaScript and TypeScript. Designed for modern Node.js environments (20+).

npm version License: MIT Bundle Size

Why Promise Pool?

Unlike other libraries that use "batching" (waiting for the slowest task in a group to finish), @mystogab/promise-pool uses a Dynamic Worker Queue. As soon as a task finishes, a worker picks up the next one immediately.

  • Safe by Default: Never throws - validation and processing errors are returned in the result object
  • Built-in Timeouts: Prevent "zombie" tasks by setting a time limit for individual executions.
  • Stream-Friendly: Supports Iterable and AsyncIterable. Process millions of items without loading them all into memory.
  • Smart Control: Stop execution gracefully using POOL_STOP_SIGNAL.
  • Dual Build: Native support for ESM and CommonJS.
  • Zero Dependencies: Ultra-light footprint for your project.

Installation

npm i @mystogab/promise-pool

Quick Start

Basic Usage

import { promisePool } from '@mystogab/promise-pool';

const items = [1, 2, 3, 4, 5];
const task = async (id) => {
  await new Promise(r => setTimeout(r, 100));
  return `Result ${id}`;
};

const { results } = await promisePool({
  input: items,
  process: task,
  concurrency: 2
});
console.log(results) // ["Result 1", "Result 2", ...];

Using onTaskStarted and onTaskFinished callbacks

import { promisePool } from '@mystogab/promise-pool';

const items = [1, 2, 3, 4, 5];
const task = async (id) => {
  await new Promise(r => setTimeout(r, 100));
  return `Result ${id}`;
};

const { results } = await promisePool({
  input: items,
  process: task,
  concurrency: 2,
  onTaskStarted: (item) => {
    console.log(`Starting task: ${item}`);
  },
  onTaskFinished: (item, result) => {
    console.log(`Finished task: ${item} with result ${result}`);
  }
});
console.log(results) // ["Result 1", "Result 2", ...];

Error Mutation & Timeouts

Ensure your pool doesn't hang if a task takes too long.

You can now use onError to transform errors before they are collected. This is especially useful for replacing the internal TIMEOUT_SIGNAL with a standard Error object.

import { promisePool, TIMEOUT_SIGNAL } from '@mystogab/promise-pool';

const { errors } = await promisePool({
  input: items,
  process: slowTask,
  timeout: 2000, // 2 seconds limit per task
  onError: (error, item) => {
    if (error === TIMEOUT_SIGNAL) {
      // Mutate the error: return a standard Error instead of the Symbol
      return new Error(`Task for item ${item.id} exceeded 2000ms`);
    }
  }
});

console.log(errors.every(err => err instanceof Error)); // true

Advanced Error Handling & Early Stop

You can stop the entire pool if a critical error occurs (e.g., Auth Token expired) using the POOL_STOP_SIGNAL.

If a critical error occurs, return POOL_STOP_SIGNAL. If your onError handler itself throws an error, the pool will capture that error and stop automatically to prevent inconsistent states.

import { promisePool, POOL_STOP_SIGNAL } from '@mystogab/promise-pool';

const { results, stoppedPrematurely } = await promisePool({
  input: hugeDataset,
  process: processData,
  concurrency: 5,
  onError: async (error, item) => {
    if (error.status === 401) {
      console.error("Critical error! Stopping pool...");
      return POOL_STOP_SIGNAL;
    }
    console.warn(`Failed item ${item.id}: ${error.message}`);
  }
});

Performance Comparison

| Feature | Standard Promise.all | Common "Batch" Pools | @mystogab/promise-pool | |---------|----------------------|----------------------|--------------------| | Memory Usage | High (loads everything) | Medium | Ultra Low (Worker-based) | | Idle Time | None | High (waits for slowest) | Zero (Continuous flow) | | Native Timeout | No | Rare | Yes | | Async Iterators | No | Limited | Native Support | | Stop Signal | No | Manual/Complex | Elegant Symbol Signal |

API Reference

promisePool<T, R>(options)

Options object parameters:

  • input: Iterable<T> | AsyncIterable<T> - The data to process.
  • process: (item: T) => Promise<R> - The async function to run for each item.
  • concurrency: number (Default: 2) - Max number of simultaneous tasks.
  • timeout: number (Optional) - Time limit in milliseconds for each task.
  • onError: (error: any, item: T) => void | Promise<void> | typeof POOL_STOP_SIGNAL (Optional) - Handler for custom logic on failure.

Returns: Promise<PoolResult<T, R>>

  • results: R[] - Array of successful results in the order they were processed.
  • errors: Error[] - Array of errors encountered during processing.
  • failedItems: T[] - Array of items that failed to process.
  • stoppedPrematurely: boolean - Whether the pool was stopped early via POOL_STOP_SIGNAL.

Benchmarking

You can measure the performance in your own environment:

console.time('Pool Speed');
const { results, errors } = await promisePool({
  input: data,
  process: task,
  concurrency: 10
});
console.timeEnd('Pool Speed');

License

MIT © [@Mystogab]

Changelog

v3.3.1 | 2026-05-15

  • Changed: Removed index parameter from onTaskStarted and onTaskFinished callbacks (callbacks now only receive item parameter)

[ EXTENDED CHANGELOG ]