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

@paulmillr/jsbt

v0.5.0

Published

JS Build Tools: build, benchmark, test libs and apps

Readme

@paulmillr/jsbt

JS Build Tools: helpers for building, benchmarking & testing secure JS apps.

  • 🤖 workflows: Secure GitHub CI actions for testing & token-less publishing of JS packages using OIDC.
  • 🏋🏻 bench: Benchmark JS projects with nanosecond resolution.
  • 📝 test: Multi-env testing framework with familiar syntax & parallel execution
  • 🏗️ jsbt: Single CLI for release builds and shared doc/tree-shaking audits
  • ⚙️ tsconfig: Strict typescript configs, friendly to type stripping
  • 🪶 No dependencies

Used by noble cryptography and others.

Usage

npm install @paulmillr/jsbt

jsr add jsr:@paulmillr/jsbt

CI workflows

Secure GitHub CI configs for testing & publishing JS packages.

The files reside in .github/workflows:

  • test-js.yml: runs tests on LTS node.js, bun, deno, linter, and calculates coverage
  • test-ts.yml: the same, but runs typescript instead of js on supported node.js (v22+) On node.js v20, it executes test:nodeold to compile files instead.
  • release.yml publishes package on NPM, JSR and creates single-file output if it exists
    • Uses brand new token-less GitHub OIDC connector to NPM, ensure to link package in npm settings first
    • The Trusted Publishing also provides provenance statements by default
    • It happens after GitHub release is created

You can copy them, or depend on them directly:

name: Publish release
on:
  release:
    types: [created]
jobs:
  release-js:
    name: 'jsbt v0.4.5'
    uses: paulmillr/jsbt/.github/workflows/release.yml@570adcfe0ed96b477bb9b35400fb43fd9406fb47
    permissions:
      contents: read
      id-token: write

bench

Benchmark JS projects with nanosecond resolution

  • Precise: 1ns resolution using process.hrtime
  • Lightweight: ~200 lines of code
  • Readable: utilizes colors and nice units, shows rel. margin of error only if it's high
import bench from '@paulmillr/jsbt/bench.js';
(async () => {
  await bench('printing', () => Promise.resolve(0));
  await bench('base', () => Promise.resolve(1));
  await bench('sqrt', 10000, () => Math.sqrt(2));
})();

Example output:

getPublicKey x 6,072 ops/sec @ 164μs/op ± 8.22% [143μs..17ms]
sign x 4,980 ops/sec @ 200μs/op
verify x 969 ops/sec @ 1ms/op
recoverPublicKey x 890 ops/sec @ 1ms/op
getSharedSecret x 585 ops/sec @ 1ms/op

test

Multi-env testing framework with familiar syntax & parallel execution.

  • Familiar syntax: similar to Mocha / Jest / Vitest
  • Multi-env: runs on node.js, deno, bun, cloudflare, browsers and others
  • No "global" magic: it.run() in the end simplifies logic and browser runs
  • Parallel: easily run in node.js and bun
  • Great UI: beautiful tree reporter, optional "quiet" dot reporter

node a.test.js

MSHOULD_FAST=1 MSHOULD_QUIET=1 node a.test.js

import { should } from 'micro-should';
import { equal } from 'node:assert';
// Any assertion library can be used e.g. Chai or Expect.js
should('add', () => {
  equal(2 + 2, 4);
});
should('work in async env', async () => {
  equal(await Promise.resolve(123), 123);
});
describe('nested', () => {
  describe('nested 2', () => {
    should('multiply', () => {
      equal(2 * 2, 4);
    });
    should.skip('disable test by using skip', () => {
      equal(true, false); // skip
    });
    // should.only('execute only one test', () => {
    //   equal(true, true);
    // });
  });
});

should.runWhen(import.meta.url);
// or
// should.run();
// should.opts.STOP_AT_ERROR = false; // default=true
// should.opts.MSHOULD_QUIET = true; // same as env var

Usage:

  • should(title, case) or it(title, case) syntax to register a test function
  • should.only, should.skip allows to limit tests to one case / skip tests
  • beforeEach, afterEach execute code before / after function in describe block
  • should.runWhen(import.meta.url) must be executed in the end
    • The helper ensures tests are not ran when imported from other file
    • It compares import.meta.url to CLI argument
  • should.run() or it.run() must always be executed in the end

ENV variables, specifiable via command line or through code:

  • MSHOULD_FAST=1 enables parallel execution in node.js and Bun. Values >1 will set worker count.
  • MSHOULD_QUIET=1 enables "quiet" dot reporter

jsbt

jsbt dispatches the release build and shared audit helpers shipped by the package.

Current subcommands:

  • jsbt esbuild: bundle one repo's test/build input via esbuild
  • jsbt readme: typecheck and execute fenced README examples
  • jsbt treeshake: audit release bundles for locals that survive bundling
  • jsbt tsdoc: audit built public declarations and examples

The published package exposes a single bin, so all of these work through:

npx --no @paulmillr/jsbt <subcommand> ...

Usage (add this as "build:release" step in package.json scripts section):

npx --no @paulmillr/jsbt esbuild test/build

Shared checker usage:

jsbt readme package.json

jsbt treeshake package.json test/build/out-treeshake

jsbt tsdoc package.json

The command would execute following subcommands and produce several files:

cd test/build
npm install
npx esbuild --bundle input.js --outfile=out/noble-hashes.js --global-name=nobleHashes
npx esbuild --bundle input.js --outfile=out/noble-hashes.min.js --global-name=nobleHashes --minify
# 11d1900e99f3aa945603bb5e7d82bdd9ec6ddf5d30e2fcab69b836840cff76d2 test/build/out/noble-hashes.js
# 0be3876ff0816c44d21a401e6572fdb76d06012c760a23a5cb771c6f612106f5 test/build/out/noble-hashes.min.js

3790 LOC noble-hashes.js
58.21 KB noble-hashes.min.js
21.10 KB +gzip
19.57 KB +zstd

tsconfig

Strict typescript v6+ configs, friendly to type stripping.

  • tsconfig.test.json is for typescript tests, with looser checks

Option descriptions:

  • isolatedDeclarations ensures types are "fast" and friendly to JSR.io
  • verbatimModuleSyntax - ensures files are friendly to "type erasure" / "type ignore" node.js and others

repo-template

Contains project skeleton, which can be used to create a new package. Replace EDIT_ME with proper value.

The template ships with npm run check, which runs jsbt readme, jsbt treeshake, and jsbt tsdoc.

License

MIT License