Dependency Cooldown Auditor
Open-source CLI that audits the dependency cooldown (min-release-age) of a JavaScript project from its lockfile, for npm, pnpm, Yarn and Bun, and prints ready-to-paste config.
- Role
- Design & Development
- Year
- 2026
- Published
- September 14, 2026
dep-cooldown is a TypeScript command-line tool that audits the dependency cooldown of a JavaScript project (npm calls it min-release-age) from the lockfile you already have: when every resolved version was actually published, how many days old it was, whether it carries provenance and whether it is deprecated. It works with npm, pnpm, Yarn and Bun, and prints the configuration block that turns the cooldown on in all four. It installs nothing: it reads the lockfile, not node_modules.
Nothing to clone or install: npx dep-cooldown
Two questions
A cooldown tells your package manager to ignore versions published less than N days ago. Almost every recent npm supply-chain campaign was detected and pulled within hours —the malicious debug and chalk versions were live for two hours— so a modest delay takes you out of the exposure window. All four managers support it natively now; what was left to answer was would it have helped? and how do I turn it on without getting the unit wrong?
It is the companion tool to npm Supply Chain: The Worm That Walked In Through Trusted Publishing, where the cooldown is the first of four measures.
Features
- All four lockfile formats:
package-lock.jsonandnpm-shrinkwrap.json(v3, v2 and v1),pnpm-lock.yaml(v9, v6 and v5, including the environment document pnpm 11+ writes),yarn.lock(classic and Berry) andbun.lock. It detects which one is there —and warns when it finds several—, tells direct dependencies from transitive ones and looks aliases up under their published name. - One table with what matters: each version’s publish date (the registry’s
time), age in days —in hours under a day—, direct or transitive, provenance (dist.attestations) and deprecation. By default it lists only what needs attention;--allshows everything and--jsongives the whole structure. --as-of <date>rewinds the clock: it measures ages against the day you installed rather than today, because install day is when the risk was highest. When omitted, the report suggests your lockfile’s own modification date.--configprints the configuration for npm, pnpm, Yarn, Bun or all four, with the unit conversion done and the official documentation URL as a comment.- Built for CI: it exits
1when anything is younger than the threshold,2on a usage error,0when everything is old enough and3when nothing is young but something could not be checked —because a check that did not run is not a pass—. Because it never installs anything, no third-party lifecycle script runs in that job. - Does not take the lockfile on faith: it checks that each entry’s
resolvedURL really is the registry tarball for that version —npm ciinstalls whatresolvedsays, not whatversionsays— and lists what has no registry date (git,file:, workspaces) as skipped instead of dropping it. - Honours your registry without leaking it: it reads
registry=and@scope:registry=from.npmrcthe way npm 11 does, never sends a token and hides URL credentials in its reports; it queries at most 8 packages at a time, with bounded time and size, and caches what it needs for 24 hours. - Tested and lean: 245 offline tests —with real lockfiles from npm 11, pnpm 7, 9 and 12, Yarn 1 and 4 and Bun, and a security review whose reproductions became tests—, CI on Node 20, 22 and 24 that installs the packed tarball and runs it the way a user would, and a single runtime dependency. It takes its own medicine: its
.npmrccarriesmin-release-age=7and CI audits its own lockfile.
The unit trap
The four managers agree on the idea and disagree on everything else, starting with the unit: npm measures in days (min-release-age), pnpm in minutes (minimumReleaseAge), Yarn in minutes (npmMinimalAgeGate, which also accepts 7d) and Bun in seconds (minimumReleaseAge). Seven days is 7, 10080, 10080 and 604800: copy pnpm’s value into Bun and you get a cooldown of under three hours without noticing. --config all does the arithmetic.
Two more details the key names hide: Yarn’s exclusion list is not named after its age gate (it is npmPreapprovedPackages, and it exempts a package from every gate), and the cooldown is enforced at install time, not at update-suggestion time, so your dependency bot will still open the PR and npm ci will fail afterwards.
What a cooldown does not stop
A cooldown buys time against a compromised publish, and nothing else. The tool says so in its own documentation, so nobody deploys it thinking otherwise:
- A compromised build runner. The May 2026 Shai-Hulud wave against TanStack came in through trusted publishing itself and minted genuine Sigstore provenance. That is why the provenance column is information, not a safety rating.
- A malicious install script. A cooldown decides which version you install, not what happens while installing it: that is what
npm ci --ignore-scriptsis for. - A campaign that outlives your threshold, or anything already pinned in your lockfile.
Against what already exists
There is prior work: pkg-age, pmsec, two different projects called npm-cooldown, screen-node, supply-chain-guard, check-outdated --min-age and npm-check-updates --cooldown. Each answers a different question, from whether a dependency is abandoned to which upgrades respect a threshold. What is new in dep-cooldown is the combination: a lockfile audit across all four formats, a retrospective --as-of simulation, provenance and deprecation in the same table, and config for all four managers. In the README’s comparison, checked against each tool’s published code on 14 September 2026, none of the other eight simulates against an arbitrary date or generates manager config, and only screen-node looks at provenance, for direct dependencies only.
Tech stack
- TypeScript, strict, compiled to ESM with tsup
- Node.js ≥ 20, with yaml as the only dependency (for
pnpm-lock.yaml) - Hand-written parsers for the npm, Yarn and Bun lockfiles
- node:test for the suite, with the registry mocked from fixtures
- GitHub Actions for CI
- MIT licence; the pieces are also exported as a library (
detectAndParse,buildAudit,createRegistryClient)
Repository
View on GitHub → · Package on npm →
Goal
To turn the best impact-to-effort measure from the npm supply-chain article into a check: know, lockfile in hand, what a cooldown would have held back on the day you installed, and switch it on in any manager without falling into the unit trap. And to write down, in the tool itself, what a cooldown does not protect you from.