Skip to content

GuideDay-to-day use. Assumes you've run a first notebook.

One package's numbers ​

A notebook that runs as a program: a package name in, as a parameter, and a few numbers about the package out, as named results. The copy below ran under Ganymede with pkg set to hono:

sh
ganymede execute package-stats.ipynb -p pkg=hono --results

--results prints what the notebook published, as JSON:

json
{"path":"package-stats.ipynb","status":"ok","results":{"package":"hono","latest":"4.13.18","stable_releases":415,"first_release":"2021-12-14","weekly_downloads":104726612}}

Any launcher can pass parameters, as a JSON object in the kernel's GANYMEDE_PARAMS environment variable; run by hand, the notebook reports on express. Comparing packages runs it from another notebook. See Parameters and named results.

A notebook run on the cdp-node kernel, shown with its saved output.Download package-stats.hono.ipynb · View on GitHub

A notebook that runs like a program: it takes a package name as a parameter and hands back a few numbers about it as named results. Run on its own, it reports on express. With Ganymede, a script, a Shortcut or another notebook runs it with a different package and reads the results by name:

sh
ganymede execute package-stats.ipynb -p pkg=hono --results

Parameters ​

jupyter.params holds the run's parameters, or {} when there are none. Destructuring with a default keeps the notebook runnable by hand.

ts
const { pkg = "express" } = jupyter.params as { pkg?: string };
pkg
'hono'

Fetch ​

The package's registry record, and last week's downloads. Neither endpoint needs a key.

ts
const record = await (await fetch(`https://registry.npmjs.org/${pkg}`)).json();
const { downloads }: { downloads: number } =
  await (await fetch(`https://api.npmjs.org/downloads/point/last-week/${pkg}`)).json();

const stable = Object.keys(record.versions).filter((v) => /^\d+\.\d+\.\d+$/.test(v));
const latest: string = record["dist-tags"].latest;
const firstRelease = record.time.created.slice(0, 10);
const lastRelease = record.time[latest].slice(0, 10);

Results ​

jupyter.result(name, value) publishes a value under a name. Each one shows as a name = value line, and whoever ran the notebook reads it as JSON, without parsing the output.

ts
jupyter.result("package", pkg);
jupyter.result("latest", latest);
jupyter.result("stable_releases", stable.length);
jupyter.result("first_release", firstRelease);
jupyter.result("weekly_downloads", downloads);
package = "hono"
latest = "4.13.18"
stable_releases = 415
first_release = "2021-12-14"
weekly_downloads = 104726612

Summary ​

For a person reading the notebook, the same numbers as a sentence.

ts
jupyter.md`**${pkg}** ${latest}, released ${lastRelease}: ${stable.length} stable releases since ${firstRelease},
and ${downloads.toLocaleString("en")} downloads last week.`

hono 4.13.18, released 2026-11-11: 415 stable releases since 2021-12-14, and 104,726,612 downloads last week.

Next ​

MIT license. Parts are ports of Deno's Jupyter kernel, © the Deno authors.