Node 18 end of life — check package metadata before publishing

Checks package.json before npm publish: engines.node floors that still admit end-of-life Node 18/20, volta and @types/node pins, non-SPDX licence values, and repository/provenance blockers. Runs entirely in your browser — nothing is uploaded.

Same engine as the VS Code extension, byte for byte.

Get the full version $29

A dated release report (Markdown) of every finding and its fix line, saved for the release ticket or audit file.

One payment, one licence key for this tool. The key is shown right after payment.

Buy the full version — $29
Want the full version?
Enter your email and we send the download link.
ENDEJAESPT

Find a tool

· ReadyStack

Worked example

Real numbers from this tool, line by line.

npm publish package.json gate: engines & SPDX

npm publish package.json: 6 findings on one library manifest, checked on 2026-09-30 — this is for npm package maintainers who publish from GitHub Actions with --provenance and still carry an engines field written in the Node 18 era.

The file

The manifest is a small scoped library, @acme/tiny-queue 3.1.0. It builds with TypeScript and publishes with provenance turned on in publishConfig. Nothing about it looks broken.

What the gate found

Six lines, each with the replacement line next to it:

  1. "license": "Apache 2.0" is not an SPDX identifier. The fix is "license": "Apache-2.0".
  2. homepage and bugs say Acme/tiny-queue, repository.url says acme/tiny-queue. npm documents that provenance needs a public repository that matches, case-sensitive, where you publish from. Pick one letter case and use it everywhere.
  3. "node": ">=18" admits Node 18 (end of life 2025-04-30) and Node 20 (end of life 2026-04-30). On 2026-09-30, Node 20 has been end-of-life for 153 days. The fix is "node": ">=22".
  4. volta pins "node": "20.11.1", so every contributor and CI job that uses Volta runs an end-of-life line. The fix is "node": "24".
  5. The package is scoped and publishes with provenance, but publishConfig has no access field. npm documents --access public for a first provenance publish. The fix is "access": "public".
  6. "@types/node": "^20.11.0" gives the compiler Node 20 types. The fix is "@types/node": "^22".

The Node line map

The first three Node findings are one migration seen from three places: engines.node, volta.node and @types/node. A maintainer who moves only engines still ships a Volta pin and types for the old line. The gate walks all of them, plus packageManager when provenance is on (npm documents 9.5.0+ for provenance), so the whole move to Node 22 fits in one list.

The date changes the answer

The gate takes 2 inputs: the package.json text and today's date. The same dirty file checked on 2026-03-01 gives 4 findings, not 6. Node 20 was still supported that day, so the volta pin and the @types/node line were fine, and the engines finding names only Node 18. The clean manifest in the bundle, with engines ">=22", gives 0 findings on 2026-09-30 and 1 warning on 2026-12-01, because Node 22 ends on 2027-04-30 and that is 150 days away.

Why a chatbot answer is not enough

A chatbot does not know what day it is, so it cannot tell you whether Node 20 is already end of life for your release. It guesses SPDX identifiers ("Apache 2.0" looks right to most readers) and never sees that two URLs in your manifest differ only in letter case. npm publish --dry-run does not judge an engines floor at all. The gate runs 17 rules on your own file, offline, with the Node release schedule dates written into the rules.

The 17 rules

Node line: engines.node missing, engines.node floor end-of-life, engines.node floor ending within 180 days, volta.node end-of-life, @types/node end-of-life, packageManager npm below 9.5.0 with provenance. Licence: missing, object or licenses array, not SPDX, deprecated SPDX id, UNLICENSED without private. Repository: missing, missing with provenance, shorthand, browser or http URL, letter-case mismatch. Access: scoped package with provenance and no public access.

Try it on your own file

Paste your package.json into the free web page or open it in VS Code and run the command. Every finding and every fix line is free, with no key. The optional full version saves a dated Markdown release report of the same findings for the release ticket.

15 seconds — what it actually does

Questions people ask

What does the npm publish package.json gate check?

It reads one package.json and applies 17 rules with 2 inputs, the file text and today's date. It flags engines.node floors that still admit end-of-life Node 18 or Node 20, volta and @types/node pins, licence values that are not SPDX, and repository or provenance blockers, and prints the exact replacement line for each finding.

Who is the package.json release gate for?

It is for npm package maintainers who publish from GitHub Actions with npm publish --provenance, and for library authors whose engines field was written when Node 18 or Node 20 was current. Node 20 reached end of life on 2026-04-30, so a range like >=18 now admits two end-of-life lines.

Why not ask a chatbot or run npm publish --dry-run?

A chatbot does not know today's date, guesses SPDX identifiers, and cannot see letter case in your repository URL. npm publish --dry-run does not judge whether your engines floor is end of life. The gate runs on your own package.json offline, with the Node release schedule end-of-life dates written into its 17 rules.

What is free and what does the full version add?

Free, with no key: every finding and every fix line, in VS Code and on the web page. On the bundled fixture that is 6 findings from 17 rules and 2 inputs. The full version, one payment and one licence key per person or team seat, saves a dated Markdown release report of every finding for the release ticket or audit file.

What does it cost compared with fixing a failed publish by hand?

The checks themselves are free. The cost it avoids is a release run that stops at the provenance step or ships an engines range admitting Node 20, which reached end of life on 2026-04-30. The full version is a one-time $29 licence for the dated report; there is no subscription.

Ask about this tool

One question, answered by the person who built it. Your email only if you want the answer sent.