Music to my ears.
Terz watches how your packages are doing (downloads, upgrades landing, stars, advisories) and plays it back on one page and in your Mac's menu bar, today. Your phone is next.
Out now · npm install -g terz-cli
A chart, mid-run. PyPI didn’t answer this cycle, so its last good reading is held rather than lost. Sample data.
Every number says whether it came back.
A source going quiet is normal. It should never take the page down, and it should never quietly hand you a stale number as if it were fresh.
Live
The source answered this cycle.
Held
The source didn’t answer. The last good reading stays on the chart, dimmed and marked with how long it has been held.
No reading
Nothing came back, and there is nothing to hold. Never shown as a zero; zero is a real measurement.
A reading for your README.
A plain SVG, drawn by the same rules as the chart: blue only when the number came back on the latest run, dimmed and hollow when it is held. No tracker, no script.
Your total
terz run writes badge.svg beside the chart: the 30-day
download total, rewritten on every run.
One package
The hosted mode serves a badge per product, at
/b/<workspace>/<product>.svg.
Held reads held
A source that did not answer keeps its last good number, dimmed, and says so to a screen reader.
The hosted mode, with alerts and a brief.
Self-hosting is free, and stays free. On the hosted mode, Free watches three packages; Pro watches every package you ship, puts your Stripe revenue beside them, and adds two things a team asks for.
Webhook alerts
A post to your Slack, Discord or any webhook when a package crosses a milestone, and
when a registry reports an advisory against your latest release. Self-hosted, set the
TERZ_WEBHOOK_URL environment variable; the URL is a secret, so it never goes
in terz.config.json.
An executive brief
The chart as a Markdown digest, ready to paste into an update.
Complete portability, on every plan
Export every reading as CSV or JSON, and sweep on demand right after a release.
Self-hosted, your history is already a file: readings.jsonl.
A collector, a contract, and every screen.
You list your packages
Once. Names and the registries they live on; that is the whole configuration.
A run happens on a timer
Every source is read, and each reading is appended to a plain file on disk. A source that fails is held, not fatal: the timer never crashes.
The page is rewritten
One static HTML file, no server. Serve it, or open it off disk. Beside it, terz.json carries the same chart as data, so every screen that reads it agrees with the chart.
On every screen you own.
Your phone coming
Native apps for iPhone and Android. Home-screen and lock-screen widgets, a Control Centre control, Siri, a quick-settings tile, and a nudge when a reading moves.
Your menu bar
A desktop app that lives in the menu bar on macOS. The number is just there, all day, without a tab open. Linux is next.
Download for macOS · Apple silicon and Intel
The chart
The one-page chart every run rewrites. It is the source of truth the apps read: one contract file, one design, everywhere.
Where the readings come from.
More sources land as each one is proven against a real registry, rather than announced ahead of it.
Self-hosted first.
The collector runs where you run it. Your numbers never leave the box, nothing here can rate-limit you or change its price, and if this site disappears tomorrow your chart still updates on your timer. And if you’d rather not run anything, the hosted mode is live at app.terz.dev, reading the same contract. Your box or ours. Your call.
npm install -g terz-cli
terz init · terz check · terz run · terz export
Needs Node.js 22 or newer (24 LTS recommended).