Skip to content

feat(wasm): support source phase imports and enable js-string builtins#22675

Open
guybedford wants to merge 1 commit into
vitejs:mainfrom
guybedford:feat/wasm-source-phase
Open

feat(wasm): support source phase imports and enable js-string builtins#22675
guybedford wants to merge 1 commit into
vitejs:mainfrom
guybedford:feat/wasm-source-phase

Conversation

@guybedford

Copy link
Copy Markdown

Follow-on to the WASM ESM Integration work, adding support for the source phase import proposal for .wasm files. A source phase import hands you the compiled WebAssembly.Module without instantiating it, so you own instantiation entirely — the standard alternative to ?init for instantiation control:

import source mod from './mod.wasm'

const instance = await WebAssembly.instantiate(mod, {
  './imports.js': { someFunc: () => {} },
})

The dynamic import.source('./mod.wasm') form resolves to the WebAssembly.Module as well.

Rather than rely on native import source support (which isn't available across all supported browsers or Node versions yet), this polyfills the proposal on top of Vite's existing module pipeline:

  • import source x from './m.wasm' is rewritten to a plain import x from './m.wasm?source', whose module resolves to a compiled WebAssembly.Module.
  • import.source('./m.wasm') becomes import('./m.wasm?source').then((m) => m.default), unwrapping the namespace default to match the native semantics where the promise resolves to the module source object.
  • In SSR the ?source module compiles via node:fs, so it works on every supported Node version regardless of whether the runtime understands the syntax. We can drop the polyfill and pass import source through natively once Node 22 reaches EOL (April 2027).

This also enables the JS String Builtins and Imported String Constants proposals on compile/instantiate, matching the WebAssembly/ES Module Integration loader.

Tests cover static and dynamic source phase imports, and source phase imports instantiated with the wasm module's own imports, in both serve and build. Docs are updated with a new "Source Phase Imports" section.

Add support for the source phase import proposal for `.wasm` files,
giving the compiled `WebAssembly.Module` so consumers own instantiation:

    import source mod from './mod.wasm'
    const instance = await WebAssembly.instantiate(mod, imports)

The dynamic `import.source('./mod.wasm')` form is supported too. This is
the standard alternative to `?init` for instantiation control.

Source phase imports are polyfilled on top of Vite's existing module
pipeline: `import source x from './m.wasm'` is rewritten to a plain import
of `./m.wasm?source`, whose module resolves to a compiled
`WebAssembly.Module`. The dynamic form additionally unwraps the namespace
default to match native semantics. This avoids relying on native
`import source` support in browsers or Node (SSR compiles via node:fs),
so it works across all supported runtimes.

Also enable the JS String Builtins and Imported String Constants proposals
on compile/instantiate, matching the WebAssembly/ES Module Integration
loader.
@guybedford guybedford force-pushed the feat/wasm-source-phase branch from d8064ba to 384f348 Compare June 13, 2026 00:28
daltino

This comment was marked as spam.

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