Skip to content

fix(nuxt): bundle rolldown wasm binding for webcontainer - #137

Merged
xKevIsDev merged 1 commit into
mainfrom
fix/nuxt-rolldown-wasm-binding
Oct 26, 2026
Merged

xKevIsDev merged 1 commit into
mainfrom
fix/nuxt-rolldown-wasm-binding

Conversation

@xKevIsDev

Copy link
Copy Markdown
Contributor

Problem

New Nuxt projects fail to install in WebContainers. nuxt prepare (the postinstall step) and nuxt dev both crash with:

ERROR  Cannot find native binding. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828).
    at eval (node_modules/rolldown/dist/shared/binding-B4m_2rFW.mjs:619:34)

Rolldown (used by Vite 8) can't load its native binary in a WebContainer. When @rolldown/binding-wasm32-wasi isn't in node_modules, Rolldown downloads it at runtime with pnpm i @rolldown/binding-wasm32-wasi@<version>. That download resolves fresh versions:

  • @rolldown/binding-wasm32-wasi@1.2.12 pins @emnapi/core and @emnapi/runtime to 2.0.0-alpha.5 and depends on @napi-rs/wasm-runtime@~1.2.4.
  • @napi-rs/wasm-runtime@1.2.6 (published 2026-10-25) changed its @emnapi peer range to ^1.7.1 || 2.0.0-beta.2, which no longer accepts alpha.5, so the binding fails to load.

The starter worked when it was added in #131 because the download picked up @napi-rs/wasm-runtime@1.2.5 at the time. Newer Rolldown bindings (up to 1.2.15) still pin alpha.5, so bumping Rolldown doesn't fix it.

Solution

Ship the WASI binding in the starter's lockfile with a known-good @napi-rs/wasm-runtime, so Rolldown finds it locally and never downloads anything at runtime.

High-Level Approach

Rolldown's loader tries the native binary first, then a locally installed @rolldown/binding-wasm32-wasi, and only falls back to the runtime pnpm download if neither loads. Adding the binding as a dependency makes the second step succeed in WebContainers. On normal machines the native binary still loads first, so nothing changes there.

Implementation Details

  • Added @rolldown/binding-wasm32-wasi at exactly 1.2.12, matching the locked rolldown version (Rolldown checks the binding version matches). The package has no cpu/os restriction, so it installs on every platform.
  • Added overrides to pin @napi-rs/wasm-runtime to 1.2.5, the last version whose peer range accepts @emnapi 2.0.0-alpha.5.
  • Updated the lockfile in place with npm 11 (same reason as feat(nuxt): add nuxt 4 starter with package-lock.json #131). The only changes are the new binding chain (@emnapi/*, @napi-rs/wasm-runtime, @tybys/wasm-util, tslib) plus two stale optional peer entries (cac, commander) dropped. nuxt 4.5.2, rolldown 1.2.12, and vite 8.3.3 are unchanged. npm ci passes with the repo's npm 10.2.3.
  • Side benefit: installs no longer pay for the roughly 5s runtime pnpm download.
  • If nuxt/vite are bumped later and rolldown moves off 1.2.12, this binding version needs to move with it.

Verified:

  • WebContainer (@webcontainer/test, Chromium): reproduced the exact error on main. With this change, npm install runs nuxt prepare cleanly with no runtime download, and npm run dev serves the "Start prompting" page.
  • Locally on macOS: npm ci, nuxt dev, and nuxt generate work, and Rolldown still loads its native binary.

Main Files Changed

  • nuxt/package.json - add @rolldown/binding-wasm32-wasi@1.2.12 and override @napi-rs/wasm-runtime to 1.2.5
  • nuxt/package-lock.json - lock the WASI binding chain

Ticket

N/A

@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@xKevIsDev
xKevIsDev marked this pull request as ready for review October 26, 2026 18:04
@xKevIsDev
xKevIsDev merged commit bfcd719 into main Oct 26, 2026
3 checks passed
@xKevIsDev
xKevIsDev deleted the fix/nuxt-rolldown-wasm-binding branch October 26, 2026 18:04
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