Skip to content

Declare the platforms and Node versions actually supported (breaking) - #455

Open
TimelordUK wants to merge 1 commit into
masterfrom
feat/declare-supported-platforms
Open

TimelordUK wants to merge 1 commit into
masterfrom
feat/declare-supported-platforms

Conversation

@TimelordUK

Copy link
Copy Markdown
Owner

As you said — the old numbers were picked when every Node ABI needed its own binary and the matrix ran past a hundred artifacts. They were a cut-off, not a support statement, and nothing verified them.

The gap that produces your "doesn't work on my Node 18 app" ticket:

engines promised node >=18
CI actually tested 22, 24, 26

So 18 and 20 were entirely untested while being advertised as supported. There's no good answer to a bug report on an untested version you promised to support.

Node: >=22

Supported now means something checkable: a Node line upstream still supports, which CI tests on every commit. Node 18 reached EOL 2025-04-30, Node 20 on 2026-04-30. So >=22 states the real position and matches the matrix exactly.

Worth being clear that nothing in the code needs a floor this high — lib/ bottoms out at Object.hasOwn (Node 16.9), node-addon-api@8 accepts ^18 || ^20 || >= 21, and N-API 8 goes back to Node 12.22. The constraint is support, not capability, and saying so out loud is the point.

32-bit Windows: the field wasn't doing what it looked like

"os": ["win32"] does not mean 32-bit. win32 is Node's platform string for all Windows — this 64-bit machine reports win32 too. And there was no cpu field at all, so 32-bit installs were permitted and then failed later at load.

"cpu": ["x64", "arm64"] produces a hard EBADPLATFORM at install instead. arm64 stays listed deliberately: there's no bundled binary, but node-gyp-build compiles from source there successfully, and dropping it would block people who currently work.

Verified, not assumed

Using fixtures whose constraints cannot match this machine:

Fixture Result
cpu: ["mips"] npm error code EBADPLATFORM, exit 1
engines: {">=99"} npm warn EBADENGINE, exit 0
same, engine-strict=true npm error code EBADENGINE, exit 1

That difference is why this is breaking. engines only warns under default npm, but pnpm and engine-strict setups fail hard, so narrowing it can break someone's install.

Also worth recording: npm's --os / --cpu flags do not simulate the check. They force optional-dependency selection; npm install --cpu=ia32 still succeeded. My first attempt to test this way gave a false pass.

Docs corrected

The README was further out of date than the release notes:

  • "Prebuilt binaries are downloaded automatically" — not since 5.5.0; they ship in the package
  • macOS listed as x64 + arm64 — only arm64 is bundled
  • Windows listed as x64 + ia32
  • glibc listed as ≥ 2.28 — the builder is Ubuntu 22.04, so 2.35+
  • "Electron binaries are published alongside Node binaries" — no separate Electron artifacts exist any more
  • "win32 is no longer supported" → "32-bit Windows (ia32)", since the old phrasing reads as dropping Windows entirely
  • the "prebuilt binary fails to load" entry no longer blames a Node ABI or Electron mismatch, which cannot be the cause for an N-API build

The release template carries the same wording so the next release inherits it.

Version

This wants 6.0.0. I deliberately did not bump package.json — that's your call and you've been doing the bumps. But please don't ship it as a 5.x minor: the pnpm/engine-strict hard-fail makes it a real break, even though plain npm only warns.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K5wuZia58hUzEqN7CvHtz9

BREAKING CHANGE: engines requires node >=22 (was >=18), and cpu is now
declared as ["x64", "arm64"], which makes npm refuse 32-bit Windows outright.

The old numbers were picked when every Node ABI needed its own binary and the
matrix ran to over a hundred artifacts; they were a cut-off, not a support
statement. Nothing verified them, and they disagreed with CI: engines promised
node >=18 while the test matrix only ever ran 22, 24 and 26. Node 18 and 20
were therefore completely untested, which is exactly the gap that produces a
"doesn't work on my Node 18 app" report we cannot answer.

Supported now means something checkable: a Node line that upstream still
supports, which CI tests on every commit. Node 18 reached end-of-life on
2025-04-30 and Node 20 on 2026-04-30, so node >=22 states the real position
and matches the matrix exactly.

Nothing in the code needed a floor this high - lib/ bottoms out at
Object.hasOwn (Node 16.9), node-addon-api 8 accepts ^18 || ^20 || >= 21, and
N-API 8 goes back to Node 12.22. The constraint is support, not capability,
and saying so is the point.

The 32-bit Windows change fixes a field that was not doing what it looked
like. `os: ["win32"]` does not mean 32-bit: win32 is Node's platform string
for ALL Windows, including 64-bit. There was no cpu field at all, so 32-bit
installs were permitted and then failed at load. Declaring cpu produces a hard
EBADPLATFORM at install instead.

Both behaviours were verified rather than assumed, using fixtures whose
constraints cannot match this machine:

  - cpu: ["mips"]          -> npm error EBADPLATFORM, exit 1
  - engines: { >=99 }      -> npm warn EBADENGINE, exit 0
                           -> with engine-strict=true: error, exit 1

That difference is why this is a breaking change. engines only warns under
default npm, but pnpm and engine-strict setups fail hard, so narrowing it can
break someone's install.

Note npm's --os / --cpu flags do NOT simulate the check - they force optional
dependency selection, and an install with --cpu=ia32 still succeeds. They are
not a way to test this.

Docs corrected to match, in README.md and the release template so the next
release inherits it rather than repeating the old claims:

  - "Prebuilt binaries are downloaded automatically" - they have not been
    since 5.5.0; they ship in the package.
  - macOS was listed as x64 + arm64; only arm64 is bundled.
  - Windows was listed as x64 + ia32.
  - glibc was listed as >= 2.28; the builder is Ubuntu 22.04, so 2.35+.
  - "Electron binaries are published alongside Node binaries" - there are no
    separate Electron artifacts any more.
  - "win32 is no longer supported" now reads "32-bit Windows (ia32)", because
    the old phrasing reads as dropping Windows entirely.
  - The "prebuilt binary fails to load" entry no longer blames a Node ABI or
    Electron mismatch, which cannot be the cause of an N-API build failing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5wuZia58hUzEqN7CvHtz9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant