From 14f5437535034d35a978cd701cf85c009eec77af Mon Sep 17 00:00:00 2001 From: bsevern Date: Thu, 28 May 2026 11:36:50 -0400 Subject: [PATCH] docs(readme): add npm downloads/mo badge scripts/render-readme-badges.mjs now fetches last-month downloads from the npm API at run time and bakes the count into a fifth badge. Stays static in git; re-run the script to refresh. Co-Authored-By: Claude Opus 4.7 --- README.md | 2 +- assets/badges/downloads.svg | 1 + scripts/render-readme-badges.mjs | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 assets/badges/downloads.svg diff --git a/README.md b/README.md index c76f79f..d547484 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Hand-drawn, sketchy React charts and flowcharts. -![npm v0.2.0](assets/badges/npm.svg) ![license MIT](assets/badges/license.svg) ![drawn with rough.js](assets/badges/drawn-with.svg) ![default vibe chaotic_notebook](assets/badges/vibe.svg) +![npm v0.2.0](assets/badges/npm.svg) ![downloads/mo](assets/badges/downloads.svg) ![license MIT](assets/badges/license.svg) ![drawn with rough.js](assets/badges/drawn-with.svg) ![default vibe chaotic_notebook](assets/badges/vibe.svg) > These badges? We ship them. See [`Badge`](src/components/Badge.tsx) and the `render-badge` / `render-github-badge` MCP tools. diff --git a/assets/badges/downloads.svg b/assets/badges/downloads.svg new file mode 100644 index 0000000..fba1e13 --- /dev/null +++ b/assets/badges/downloads.svg @@ -0,0 +1 @@ +downloads/mo272 \ No newline at end of file diff --git a/scripts/render-readme-badges.mjs b/scripts/render-readme-badges.mjs index 136aa22..0ac9319 100644 --- a/scripts/render-readme-badges.mjs +++ b/scripts/render-readme-badges.mjs @@ -25,8 +25,28 @@ const BRAND = { font: 'sans-serif', }; +function formatCount(n) { + if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1).replace(/\.0$/, '')}M`; + if (n >= 1_000) return `${(n / 1_000).toFixed(1).replace(/\.0$/, '')}k`; + return String(n); +} + +async function fetchNpmDownloads(pkg, period = 'last-month') { + const url = `https://api.npmjs.org/downloads/point/${period}/${pkg}`; + const r = await fetch(url); + if (!r.ok) throw new Error(`npm downloads fetch failed: ${r.status}`); + const j = await r.json(); + return j.downloads; +} + +const monthlyDownloads = await fetchNpmDownloads('goldenchart', 'last-month'); +console.log(` fetched npm last-month downloads: ${monthlyDownloads}`); + const badges = [ { file: 'npm.svg', label: 'npm', value: 'v0.2.0', tone: 'info', icon: 'tag' }, + // No icon: the v1 BADGE_ICONS set has no download glyph and "downloads/mo" + // as a label is clear enough on its own. + { file: 'downloads.svg', label: 'downloads/mo', value: formatCount(monthlyDownloads), tone: 'info' }, { file: 'license.svg', label: 'license', value: 'MIT', tone: 'neutral', icon: 'license' }, { file: 'drawn-with.svg', label: 'drawn with', value: 'rough.js', tone: 'neutral' }, { file: 'vibe.svg', label: 'default vibe', value: 'chaotic_notebook', tone: 'info', icon: 'star' },