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

@stack-fintech/benchmark

v0.4.0

Published

A simple framework for benchmarking your functions.

Readme

benchmark

A simple framework for benchmarking your functions.

Install

npm i --save @stack-fintech/benchmark

Usage

This example should give you everything you need to setup your own benchmarks!

// The benchmark tools are comprised of these three classes:
const { Suite, Step, Test } = require("@stack-fintech/benchmark");

const crypto = require("crypto"); // Not always required, just for this example.
const Widget = require("./lib/widget"); // Some example thing you're testing.

// Suites take a collection of Tests and run them in the order they're added to the Suite.
const suite = new Suite("YourSuite");

/*
  Tests run a collection of Steps, for a given number of iterations, and produce
  statistics for each Step.

  Each iteration runs all of the Steps once, in the order they're added to the Test.
*/
const test = new Test({
  name: "widget-flow",
  iterations: 10000,
});

// Steps require a name for tracking statistics.
const makeWidget = new Step("makeWidget");

// The setup and teardown functions let you prep and cleanup before a Step runs,
// without that overhead contaminating your benchmark data.
let widgetName;
let createdWidget;

makeWidget.setup(() => {
  // Generate a random name for the widget.
  widgetName = crypto.randomBytes(16).toString("hex");
});

makeWidget.teardown(() => {
  // If you need to clean something up, you'd do it here.
});

// You can give the function handler sync or async functions.
makeWidget.fn(async () => {
  createdWidget = await Widget.create(widgetName);
});

// You can use event handlers instead if your code is event-driven.
// Note that you must:
// - make sure the event is being emitted, otherwise your Test will
// hang.
// - accept a callback as the last parameter of your handler function
// and call it when finished.
makeWidget.event(Widget, "ordered", (cb) => {
  Widget.create(widgetName)
    .then(() => {
      return cb();
    })
    .catch((err) => {
      return cb(err);
    });
});

// Steps can also be created with object definitions.

// Note: You still need to use the Step constructor, as the Test class
// expects certain properties for validation.
const shipWidget = new Step({
  name: "shipWidget",
  fn: () => {
    Widget.ship(createdWidget);
  },
});

// Assemble your test
test.add(makeWidget);
test.add(shipWidget);

// And then assemble your suite.
suite.add(test);

/*
  Suites and Tests are EventEmitters, and you can hook into them!
  
  Tests:
    start:    When Test.start is called. Provides the callback with the Test's
              options object as a parameter.
    cycle:    At the top of each iteration, before any of the steps run. Provides
              the callback with a context object that has an index (the current
              iteration), and the maximum number of iterations:
              (ex. { index: 4, iterations: 10000 })
    step:     Before each step in a cycle. Provides the callback with a context
              object that has an index (the current iteration), the maximum
              number of iterations, and the Step object.
              (ex. { index: 4, iterations: 10000, step: { ... } })
    complete: At the end of the test run. Provides the callback with a copy of
              the Test itself.
  Suites:
    start:    When Suite.start is called.
    cycle:    Identical to the "cycle" event for Tests. Useful for applying the
              same function calls to multiple test runs.
    step:     Identical to the "step" event for Tests. Again, useful if you
              want to run the same function on every Step of multiple Tests.
    complete: At the end of Suite.start, when all Tests have finished.
 */

test.on("cycle", (context) => {
  // These event emitters are *very* useful for adding your own progress tracking,
  // like progress bars, spinners, etc.
  console.log(`Run ${context.index} of ${context.iterations}`);
});

test.on("complete", () => {
  for (let step of test.steps) {
    // Test provides a printStats function you can use to print the results to stdout.
    test.printStats(step.name, test.stats[step.name]);
    // Alternatively, you can access the test.stats object and roll your own!
  }
});

(async () => {
  await suite.start(); // And that's how you do it!
})();