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

bismar

v0.1.9

Published

Browse, weigh, and diff packages from npm, jsr, crates.io, rubygems, pypi, packagist, github

Readme

bismar

Browse, weigh, and diff packages from any registry

A bismar is the old Viking hand scale for weighing goods. This one works with npm, jsr, crates.io, rubygems, pypi, packagist, github, gitlab, and the go proxy; allowing to:

  1. Browse code in interactive keyboard-friendly navigator
  2. Compare diffs between different versions
  3. Download files
  4. Easily use tool output in machine-friendly non-TTY env

For JS, bismar can also bundle and minify specific exports, with tree shaking.

Used by noble cryptography to ensure bundles stay small.

Usage

npm install bismar — or, without installing, npx bismar js:preact -bs from any directory. npm/jsr selectors and JS measurement require npm 11.15 or newer.

usage:
  bismar [<selector>] [--bundle] [--minify] [--size] [--list]
  bismar [-bms] [<selector>]
  bismar --diff <a> <b>

flags:
  <no flag>     open interactive navigator
  -b, --bundle  emit a single-file bundle (JS) / archive (non-JS)
  -m, --minify  (JS only) emit the minified bundle
  -s, --size    list shipped file size stats
      -bs       (JS) bundle sizes
      -bsm      (JS) bundle sizes, minified+gzipped
  -d, --diff    interactive comparison between 2 selectors
      -ds       non-interactive size stats for all files
      -dbs      (JS) diff of bundle sizes
      -dbsm     (JS) diff of bundle sizes, minified+gzipped
  -l, --list    list all public exports
      --clear   clean-up bismar cache

Examples

bismar js:@noble/hashes           # vim-like pager
bismar rs:serde
bismar gem:sinatra/README.md
bismar gh:@paulmillr              # user repos
bismar gem:sinatra/lib/sinatra.rb > s.rb

bismar -l npm:micro-ftch

bismar -b js:qr > qr.js
bismar -b rs:serde > serde.cargo
bismar -bm js:qr > qr.min.js

bismar -s js:chokidar
bismar -bs npm:micro-ftch
bismar -bsm npm:micro-ftch

bismar -d js:[email protected] js:[email protected]
bismar -ds npm:readdirp@{4,5}
bismar -dbs npm:readdirp@{4,5}
bismar -dbsm npm:readdirp@{4,5}

# hint: non-terminal (non-TTY) emits DIFFERENT, machine-friendly output
bismar -d npm:micro-ftch@{1.0,1.1} | head
bismar -bsm npm:react | sort -t, -k4 -rn

Selectors & namespaces

selectors (package / ref / dir / archive):
  npm:qr, npm:[email protected], gem:sinatra, ../sinatra, ./qr.tar.bz2

namespaces ("short: long"; both versions work):
  js:   npm         py:   pypi
  jsr:  jsr         php:  packagist
  rs:   crate       gh:   github
  rb:   gem         go:   go proxy
  gitlab: gitlab

Security

flowchart LR
  B[bismar] --> W["micro-ftch: host allowlist, per redirect hop, GET/HEAD only, rate-limited, BISMAR_LOG"]
  W -->|allowed hosts, table below| R[registries]
  W x--x|refused before send| X[any other host]
  B --> N["npm 11.15+ subprocess (npm/jsr) --ignore-scripts --prefer-offline"]
  N -->|registry dependencies only; file, directory, git, remote denied| NR[npm registry]
  R --> C["$TMPDIR/bismar-* caches; removed on reboot or --clear"]
  NR --> C
  • GET+HEAD only traffic: no POSTs; --no-audit removes npm's one routine POST too.
  • Host allowlist, enforced pre-send: only the origins below are reachable. Same with download URLs, except packagist (github zipballs) and pypi (pythonhosted).
  • No code execution: npm runs --ignore-scripts; bundling and measuring are static esbuild work; non-JS packages are never executed or bundled.
  • Registry-only npm dependency graph: npm 11.15+ source controls reject file, directory, git, and remote URL dependencies. Local measurement workflows grant a root-only exception for the single file or directory bismar supplied.
  • Inert terminal output: registry text, paths, source, diffs, errors, and CSV have controls neutralized; only bismar's own color sequences survive.
  • Bounded, link-free archives: metadata and downloads have streaming hard limits; extraction rejects traversal, links, special files, unsafe Windows names, and expansion/member/path bombs before trusting the resulting tree.
  • Confined packages, verified caches: downloaded manifest paths, generated entries, and imports stay inside their install root. Private atomic caches use SHA-256 identities/digests; git pins retain full GitHub SHA-1 and GitLab SHA-1/SHA-256 commit IDs.
  • Big downloads ask first: 100mb+ needs a terminal confirmation; plain refusal in scripts and CI (use BISMAR_BIG=1)
  • Disposable caches: everything lives under $TMPDIR/bismar-*, OS-cleaned after reboot; bismar --clear wipes it now. Pinned versions cache until reboot, floating "latest" for 15 minutes.
  • Knobs: BISMAR_LOG=file.txt logs every request, one line each; BISMAR_RPS tunes the polite request budget (0 disables); overriding a BISMAR_* base admits that origin in place of the default.

| host | used for | | ------------------------------ | --------------------------------------------------- | | registry.npmjs.org | npm search, profiles, packed-size garnish | | npm.jsr.io | jsr metadata + tarballs (jsr's npm-compat registry) | | api.jsr.io | jsr search, scope profiles | | crates.io (→ static.crates.io) | crate metadata, downloads, search, profiles | | rubygems.org | gem metadata, downloads, search, owner profiles | | pypi.org | pypi metadata | | files.pythonhosted.org | pypi artifact downloads | | repo.packagist.org | composer p2 metadata | | packagist.org | composer vendor profiles | | api.github.com | gh api, search, profiles; composer dist zipballs | | codeload.github.com | gh archive downloads; composer dist zipballs | | gitlab.com | gitlab api, search, profiles, archives | | proxy.golang.org | go module metadata + zips |

Three deps are used: esbuild and micro-ftch are pinned, and the syntax highlighter is vendored and bundled with the package, so none can update underneath a release.

License

MIT License (c) 2026 Paul Miller (https://paulmillr.com)