Skip to content

node: unflag addon-modules (ESM import of native .node addons on prior versions)#33

Merged
colinhacks merged 1 commit into
mainfrom
node-unflag-addon-modules
Jun 20, 2026
Merged

node: unflag addon-modules (ESM import of native .node addons on prior versions)#33
colinhacks merged 1 commit into
mainfrom
node-unflag-addon-modules

Conversation

@colinhacks

Copy link
Copy Markdown
Contributor

Adds an Unflag matrix row for --experimental-addon-modules, so ES modules can import native .node addons directly (import addon from './foo.node') on the Node versions where the flag exists.

Bands (verified against .repos/node)

The flag was added on the 23.x line at 23.6.0 and backported to the 22.x LTS line at 22.20.0 (doc/api/cli.md added: [v23.6.0, v22.20.0] — the same dual-line split as node:sqlite). It is Stability 1.0 (Early development) and never default-on (experimental_addon_modules = EXPERIMENTALS_DEFAULT_VALUE = false, confirmed through Node 27 nightly), so the Unflag bands are open-ended on the high side — there is no native cutover.

Injection set: [22.20.0, 23.0.0)[23.6.0, ∞). The flag does not exist below 22.20.0 (compat tier) or on [23.0.0, 23.6.0) (the 23.x line before the backport), where injecting it is a "bad option" startup abort, so those ranges are excluded. The flag is kAllowedInEnvvar, so it is safe in NODE_OPTIONS.

Changes

  • crates/nub-core/src/node/feature_matrix.rs: new addon-modules row + band tests (the two disjoint bands, the [23.0, 23.6) hole, and the compat-tier exclusion).
  • site/content/docs/runtime/index.mdx: addon-imports row in the Modern APIs table, version-banded and factual.

Verification

  • cargo test -p nub-core --lib — 274 passed.
  • cargo clippy -p nub-core --lib — clean.
  • cargo fmt — clean.

Greenlit (consistent with the shadow-realm posture: routinely unflag Stability-1 experimental features Node is not discouraging; --node opts out).

https://claude.ai/code/session_01YRvztkcr4fzfg9rD5edUwa

…r versions)

Add an Unflag matrix row for --experimental-addon-modules so that ES modules
can import native .node addons directly. The flag landed on the 23.x line at
23.6.0 and was backported to 22.x LTS at 22.20.0 (same dual-line split as
node:sqlite); it is Stability 1.0 and never default-on, so injection is
open-ended on the high side. Injection set: [22.20.0, 23.0.0) and [23.6.0, inf).
Below 22.20 and on [23.0, 23.6) the flag does not exist, so it is excluded.

Adds band tests for the two disjoint bands and the [23.0, 23.6) hole, and a
row in the site Modern APIs table.

Claude-Session: https://claude.ai/code/session_01YRvztkcr4fzfg9rD5edUwa
Copilot AI review requested due to automatic review settings June 20, 2026 21:53
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nub Ready Ready Preview, Comment Jun 20, 2026 9:55pm

Request Review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds feature-matrix support and documentation for unflagging Node’s --experimental-addon-modules, enabling ESM import of native .node addons on the Node versions where the flag exists.

Changes:

  • Added addon-modules feature matrix entry with two disjoint Unflag bands.
  • Added/extended tests covering the [23.0, 23.6) “hole” and compat-tier exclusion.
  • Documented “addon imports” in the runtime Modern APIs table with version banding notes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
site/content/docs/runtime/index.mdx Documents addon .node ESM imports as a Modern API and explains version constraints.
crates/nub-core/src/node/feature_matrix.rs Adds addon-modules Unflag bands and tests for the two supported ranges and excluded ranges.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +101 to +103
| [addon imports](https://nodejs.org/api/esm.html#node-addons) | Node 22.20 | flag-injected, never native |

A dash means the API works across the full supported range, 18.19 and up. The three floored rows have a real cutoff, because the underlying Node mechanism doesn't exist below it:
A dash means the API works across the full supported range, 18.19 and up. The floored rows have a real cutoff, because the underlying Node mechanism doesn't exist below it:
- The `WebSocket` global needs Node 20.10 — the flag Nub injects below the native line (Node 22) doesn't exist on older 20.x patches.
- The `EventSource` global needs Node 20.18, the patch where Node added the flag on the 20 LTS line.
- The `node:sqlite` module needs Node 22.5, where Node first shipped it.
- Importing a native `.node` addon from an ES module needs Node 22.20 (or 23.6 on the 23 line), where Node added the flag Nub injects. It is never native — Node keeps the import behind the flag — so Nub injects it on every version that has it.
Comment on lines +204 to +214
name: "addon-modules",
mitigations: &[
(
band((22, 20, 0), Some((23, 0, 0))),
Mitigation::Unflag("--experimental-addon-modules"),
),
(
band((23, 6, 0), None),
Mitigation::Unflag("--experimental-addon-modules"),
),
],
@colinhacks colinhacks merged commit d7541fd into main Jun 20, 2026
27 checks passed
@colinhacks colinhacks deleted the node-unflag-addon-modules branch June 20, 2026 23:26
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.

2 participants