Skip to content

node: unflag wasm-modules (compat-backfill) + shadow-realm#31

Merged
colinhacks merged 1 commit into
mainfrom
node-unflag-wasm-shadowrealm
Jun 21, 2026
Merged

node: unflag wasm-modules (compat-backfill) + shadow-realm#31
colinhacks merged 1 commit into
mainfrom
node-unflag-wasm-shadowrealm

Conversation

@colinhacks

Copy link
Copy Markdown
Contributor

Adds two feature-matrix rows so nub auto-injects the experimental flag on the Node versions that still require it.

wasm-modules (mechanical compat-backfill)

`importof.wasmfiles is **default-on in current Node** — the--experimental-wasm-modules` flag became a NoOp at 24.5.0 (24.x line) and 22.19.0 (22.x line) via nodejs/node#57038. Per the unflag-on-prior-versions rule (default-on in current Node ⇒ backfill it where it was flagged), this is a mechanical banded unflag, same shape as the live sqlite row.

Bands (injected where the flag both exists and is required):

[18.19, 22.19)  inject   # 22.x line, pre-backport
[22.19, 23.0)   native   # backport landed
[23.0,  24.5)   inject   # 23.x EOL before the backport — stays flagged
[24.5,  inf)    native   # default-on

The 23.x line never received the #57038 backport (EOL before 24.5), so it stays flagged through the end of the line — verified against .repos/node doc/api/esm.md.

Resolver passthrough: nub leaves .wasm import specifiers untouched. TRANSPILE_EXTS covers only .ts/.tsx/.mts/.cts/.jsx, and the additive resolver (resolveTs) returns null for a .wasm specifier, so it falls through to Node native wasm loader — no transform, no re-resolve.

shadow-realm

--experimental-shadow-realm exists from Node 18.13/19.0 (below the floor) and has never been made default-on through Node 26 (TC39 Stage 3, rides V8 --harmony-shadow-realm staging). Inject across the whole supported floor [18.19, inf), like vm-modules.

Important

shadow-realm is NOT the mechanical case wasm-modules is — it is a Stage-3, not-default-on-anywhere global, and turning it on by default is a product/posture call, not a backport. The thread .fray/v0x-shadow-realm-unflag.md recommends DEFER. It is included here per a coordinator-relayed decision, but a coordinator relay is not user authority — this row needs Colin own sign-off before merge. If the call is to defer, drop the shadow-realm commit/row and ship wasm-modules alone.

Tests

  • Band tests in feature_matrix.rs (matrix layer) and end-to-end compute_inject_flags band tests in flags.rs (the spawn path) for both features.
  • cargo test -p nub-core --lib → 274 passed; clippy + fmt clean.

https://claude.ai/code/session_01YRvztkcr4fzfg9rD5edUwa

Copilot AI review requested due to automatic review settings June 20, 2026 20:59
@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 11:56pm

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

Adds new Node feature-matrix entries so Nub can auto-inject experimental flags on Node versions that still require them, and documents the resulting “Modern APIs” surface in the runtime docs.

Changes:

  • Add wasm-modules version bands to inject --experimental-wasm-modules only where still required.
  • Add shadow-realm entry to inject --experimental-shadow-realm across the supported floor, plus tests.
  • Update runtime docs “Modern APIs” table with new rows for ShadowRealm and Wasm module imports.

Reviewed changes

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

File Description
site/content/docs/runtime/index.mdx Adds Modern APIs table rows for ShadowRealm and Wasm module imports.
crates/nub-core/src/node/flags.rs Adds band/injection tests for wasm-modules and shadow-realm via compute_inject_flags.
crates/nub-core/src/node/feature_matrix.rs Adds new feature-matrix rows + band tests for shadow-realm and wasm-modules.

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

Comment on lines +152 to +156
// ── ShadowRealm global ──────────────────────────────────────────────────
// `--experimental-shadow-realm` gates `globalThis.ShadowRealm` (TC39 Stage 3:
// an isolated global with fresh intrinsics). The flag was added in Node
// 18.13.0 / 19.0.0 — below nub's 18.19 floor — and has NEVER been made
// default-on through Node 26 (still experimental, rides the V8
Comment on lines 97 to +99
| [`vm.Module`](https://nodejs.org/api/vm.html#class-vmmodule) | — | flag-injected |
| [`ShadowRealm`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ShadowRealm) | — | flag-injected |
| [Wasm module imports](https://nodejs.org/api/esm.html#wasm-modules) | — | flag-injected below Node 24.5 (22.19 on the 22.x line), native above |
Comment on lines +213 to +216
// from './x.wasm'`). The flag has existed since Node 12 — far below nub's
// 18.19 floor — so it both EXISTS and is REQUIRED across the whole compat
// range below the default-on cutover. It became default-on (flag → NoOp) at
// 24.5.0 on the 24.x line and was backported to 22.19.0 on the 22.x line
@colinhacks

Copy link
Copy Markdown
Contributor Author

CI failure — do not merge

Test (macos-14, node 24) and Test (windows-latest, node 24) fail. Both on the same bug introduced by the shadow-realm row:

ERR_WORKER_INVALID_EXEC_ARGV: Initiated Worker with invalid execArgv flags: --harmony-shadow-realm

Root cause: --experimental-shadow-realm implies --harmony-shadow-realm internally. Node adds the implied V8 harmony flag to process.execArgv. The worker polyfill (runtime/worker-polyfill.mjs:120) passes process.execArgv directly to NodeWorker — Node 24 rejects --harmony-* flags in worker execArgv with ERR_WORKER_INVALID_EXEC_ARGV.

Failing tests: worker_transpiles_ts_entry, worker_message_roundtrip, worker_throw_surfaces_to_parent_onerror — all worker tests on Node 24.16.0.

Fix required in runtime/worker-polyfill.mjs (line 120): filter --harmony-* flags from execArgv before passing to NodeWorker:

execArgv: process.execArgv.filter(f => !f.startsWith('--harmony')),

This is the correct fix regardless — any harmony-implying flag injected by nub would trigger this. The filter is safe: harmony flags are V8 internals that Node documents as invalid for workers.

This fix should land before or with this PR. The wasm-modules row is clean; only shadow-realm triggers this.

@colinhacks colinhacks force-pushed the node-unflag-wasm-shadowrealm branch from d90f908 to edb2567 Compare June 20, 2026 23:54
@colinhacks colinhacks merged commit 54cb42e into main Jun 21, 2026
26 checks passed
@colinhacks colinhacks deleted the node-unflag-wasm-shadowrealm branch June 21, 2026 02:09
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