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

js-queue

v3.1.1

Published

A tiny FIFO task queue with explicit flow control for Node and browsers

Readme

js-queue — explicit FIFO flow control for JavaScript

js-queue

A tiny first-in-first-out task queue with explicit flow control. Add functions, let the queue start automatically, and call this.next() when each task is ready to release the next one.

Documentation · Quick start · API · Patterns · Browser use · Examples · Playground · Performance · Testing

CI Pages npm version npm downloads license

Install

npm install js-queue

Native ES modules:

import Queue from 'js-queue';

const queue=new Queue;

queue.add(
    function(){
        console.log('first');
        this.next();
    },
    function(){
        console.log('second');
        this.next();
    }
);

CommonJS remains supported:

const Queue=require('js-queue');

Browser ESM: bundler or no bundler

js-queue works with bundlers and without a bundler. Bundlers resolve the bare package imports normally. Native browser ESM uses a standard import map and runs the same JavaScript directly, with no build or transpilation step.

For a normal npm layout where easy-stack is hoisted, place this complete import map before the module script:

<script type="importmap">
{
  "imports": {
    "js-queue": "./node_modules/js-queue/queue.js",
    "js-queue/": "./node_modules/js-queue/",
    "js-queue/stack": "./node_modules/js-queue/stack.js",
    "js-queue/stack.js": "./node_modules/js-queue/stack.js",
    "easy-stack": "./node_modules/easy-stack/stack.js"
  }
}
</script>
<script type="module">
  import Queue from 'js-queue';
  import Stack from 'js-queue/stack';

  const queue=new Queue;
  const stack=new Stack;
</script>

If npm nests easy-stack because the application installs a conflicting root version, use this complete scoped map instead. Its scope preserves the dependency boundary that Node and bundlers apply to imports originating inside js-queue:

<script type="importmap">
{
  "imports": {
    "js-queue": "./node_modules/js-queue/queue.js",
    "js-queue/": "./node_modules/js-queue/",
    "js-queue/stack": "./node_modules/js-queue/stack.js",
    "js-queue/stack.js": "./node_modules/js-queue/stack.js",
    "easy-stack": "./node_modules/easy-stack/stack.js"
  },
  "scopes": {
    "./node_modules/js-queue/": {
      "easy-stack": "./node_modules/js-queue/node_modules/easy-stack/stack.js"
    }
  }
}
</script>
<script type="module">
  import Stack from 'js-queue/stack';

  const stack=new Stack;
</script>

Every import-map URL is relative to the HTML document. Serve the application over HTTP(S), and configure that server to expose the mapped node_modules files. file:// is not a supported loading path. See the browser guide for the classic-script option and live no-bundler examples.

The flow contract

js-queue does not guess when a task is complete. A task releases the next item by calling this.next()—immediately, from a callback, or after an awaited operation.

queue.add(function(){
    fetch('/work')
        .then(handleResponse)
        .finally(()=>this.next());
});

That explicit hand-off makes the same queue useful for synchronous steps, callback APIs, network work, connection gates, and manually controlled pipelines.

Performance

The fastest js-queue yet. Install it. Don’t rebuild it.

Constructing 100,000 queues: js-queue 3.1.0 is 19.86 times faster than 3.0.0

Scheduling and draining 100,000 tasks: js-queue 3.1.0 is 1.41 times faster than 3.0.0

Node 24.18, 100,000 operations, median of 21 alternating samples. Method and results. CI reruns the tagged comparison.

Public surface

| Member | Type | Purpose | | --- | --- | --- | | add(...tasks) | method | Validate and append functions; auto-start when idle. | | next() | method | Run the next FIFO task when the queue is not stopped. | | clear() | method | Remove pending tasks and return the new empty array. | | contents | getter/setter | Read or replace the pending function array. | | size | getter | Number of pending tasks. | | running | getter | Whether a task currently owns the queue. | | autoRun | boolean | Start automatically after add(); defaults to true. | | stop | boolean | Hold execution without discarding pending work. |

Every task receives the queue as this. Invalid tasks are rejected before any item from the same add() call is appended. If a task throws synchronously, the queue returns to an idle, recoverable state and preserves the remaining work.

Entry points

| Import | Format | Use | | --- | --- | --- | | js-queue | ESM or CommonJS | Conditional primary entry. | | js-queue/queue.js | ESM or CommonJS | Compatibility path to the queue. | | js-queue/queue-vanilla.js | classic browser script | Publishes globalThis.Queue. | | js-queue/stack | ESM or CommonJS | The modernized easy-stack 2.1 LIFO entry. |

The runtime supports Node.js 22.13 and newer. Native ESM and CommonJS both load the same synchronous source files; no duplicate Node build is shipped.

Test and coverage evidence

Tested with vanilla-test. The repository has 102 focused checks organized into five non-overlapping layers: Unit, Functional, Behavioral, Integration, and Regression. Forty-two shared checks import the package by its bare name and run unchanged in Node and real Google Chrome; Chrome resolves those imports through the checked-in import-map configuration.

npm test
npm run test:unit
npm run test:functional
npm run test:behavioral
npm run test:integration
npm run test:regression
npm run test:consumer
npm run coverage

The 10 Unit checks isolate API facts. The 30 Functional checks cover queue workflows and Playground behavior. The 9 Behavioral checks verify complete consumer outcomes across explicit hand-offs, gates, recovery policies, stale-reference isolation, independent queues, reprioritization, and native no-bundler loading. The 28 Integration checks cover interacting queue operations, package formats, a poisoned packed-consumer dependency conflict, benchmark evidence, stack compatibility, and local HTTP delivery. The 25 Regression checks protect validation, recovery, the no-WeakMap performance contract, import maps, documentation, artwork, and deployment wiring. Both native V8 collectors continue to enforce 100% statement, branch, function, and line coverage for the shipped ESM queue.

Node coverage report · Chrome coverage report

Version 3.1

Version 3.1 replaces WeakMap lookups with private instance fields, shares one Node source between import and require, and moves the runtime floor to Node 22.13. Existing require('js-queue') and require('js-queue/stack.js') syntax remains supported on that Node floor; queue-vanilla.js remains available to current browsers with native private fields.

Read the migration guide and changelog before upgrading an application on Node versions older than 22.13.

License

MIT