Skip to content

feat(bindings/node): publish @swc/core-wasm32-wasi (napi-rs wasi build) - #12064

Open
Michael Kremenetsky (michaelkremenetsky) wants to merge 2 commits into
swc-project:mainfrom
michaelkremenetsky:feat/core-wasm32-wasi
Open

feat(bindings/node): publish @swc/core-wasm32-wasi (napi-rs wasi build)#12064
Michael Kremenetsky (michaelkremenetsky) wants to merge 2 commits into
swc-project:mainfrom
michaelkremenetsky:feat/core-wasm32-wasi

Conversation

@michaelkremenetsky

@michaelkremenetsky Michael Kremenetsky (michaelkremenetsky) commented Jul 22, 2026

Copy link
Copy Markdown

The napi-rs loader in packages/core/binding.js already tries require('@swc/core-wasm32-wasi') as its last fallback, but that package has never actually been built or published. So on any wasm32 runtime, require('@swc/core') just dies with Failed to load native binding before the @swc/wasm fallback in index.js ever gets a chance to run.

This matters for in-browser Node runtimes like WebContainers and Strapkit, where everything runs on wasm32-wasi and there is no native binary to load. In practice anything that pulls in @swc/core@swc/cli builds (swc src -d dist), @swc/jest, webpack's swc-loader, @vitejs/plugin-react-swc — is currently broken in those environments, and each runtime ends up carrying its own workaround. rolldown, oxc and rspack all publish a wasi binding through the same napi-rs pipeline, so swc is really the odd one out here.

What this PR does:

  • adds wasm32-wasip1-threads to napi.targets in packages/core/package.json, so napi artifacts picks up the wasi files and napi prepublish adds @swc/core-wasm32-wasi to optionalDependencies (cpu: ["wasm32"] keeps it off native installs)
  • adds packages/core/scripts/npm/wasm32-wasi/ mirroring the other per-target npm dirs
  • adds a build matrix entry to publish-npm-package.yml. It only builds for @swc/core (the other packages skip it and the artifact upload tolerates that), and the upload glob now also grabs the napi-generated wasi-worker* files. I skipped the swc CLI binary for this target on purpose — a wasi CLI build is a separate discussion.

binding.js (generated by napi-rs) already probes for @swc/core-wasm32-wasi
as its wasi fallback, but the package was never built or published, so
require('@swc/core') throws 'Failed to load native binding' on every
wasm32-wasi runtime. binding_core_node compiles for wasm32-wasip1-threads
with no source changes when the plugin feature (wasmer, which cannot run
inside a wasm module) is disabled, matching the plugin-less targets that
already build with --no-default-features --features swc_v1.

- add wasm32-wasip1-threads to packages/core napi.targets so
  napi artifacts / napi prepublish pick up the new package
- add packages/core/scripts/npm/wasm32-wasi (package.json + README),
  mirroring the other per-target npm dirs
- add a publish matrix entry building the target for @swc/core only,
  and include the napi-generated wasi-worker files in the artifact upload
@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d82653

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant

CLAassistant commented Jul 22, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@socket-security

socket-security Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​napi-rs/​wasm-runtime@​1.1.61001007192100

View full report

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bd2a545df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +44 to +46
"dependencies": {
"@napi-rs/wasm-runtime": "^1.1.6"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Update the pnpm lockfile for the new workspace

Adding this package under packages/core/scripts/npm/* makes it a workspace importer, and it also introduces @napi-rs/wasm-runtime@^1.1.6, but pnpm-lock.yaml was not updated: the lockfile still lists the existing core npm subpackages and has no packages/core/scripts/npm/wasm32-wasi importer. The release workflow runs pnpm install --frozen-lockfile before building/publishing, so any release tag containing this new package.json will fail during install until the lockfile includes this workspace and dependency resolution.

Useful? React with 👍 / 👎.

@codspeed-hq

codspeed-hq Bot commented Jul 22, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 3.18%

⚡ 1 improved benchmark
✅ 188 untouched benchmarks
⏩ 61 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation es/lints/libs/three 50.6 ms 49.1 ms +3.18%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing michaelkremenetsky:feat/core-wasm32-wasi (6d82653) with main (1e3ed5c)

Open in CodSpeed

Footnotes

  1. 61 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

The new packages/core/scripts/npm/wasm32-wasi dir is a workspace importer
(the scripts/npm/* glob) and adds @napi-rs/wasm-runtime, so the release
workflow's pnpm install --frozen-lockfile needs the lockfile to know both.
Regenerated with the pinned pnpm (10.33.3) via install --lockfile-only;
the @emnapi/core peer-suffix churn on @napi-rs/cli comes from
@napi-rs/wasm-runtime entering the graph, and the @swc/core peer-context
bumps are the lockfile catching up to the current workspace versions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants