WebAssembly
Rslib supports building libraries that import WebAssembly (.wasm) modules.
You can use WebAssembly ESM Integration syntax in your source code:
API
Use wasm in the lib config to configure how Rslib handles direct .wasm imports.
- Type:
When mode is not specified, Rslib selects the default mode based on bundle:
To control the behavior explicitly, set wasm.mode:
wasm.mode
mode controls how direct .wasm imports are handled.
compile: Rspack parses the.wasmmodule and generates JavaScript glue code and runtime loading logic. See Compile mode.preserve: Rslib preserves the.wasmimport in the output and emits the binary for downstream tools or runtimes that support WebAssembly ESM Integration. See Preserve mode.
mode is only effective for ESM output. See Limitations.
Compile mode
In compile mode, Rspack compiles the .wasm module and generates JavaScript code that loads and instantiates it at runtime.
Compile mode emits the WebAssembly binary as an asset. The output path follows Rsbuild's output.distPath.wasm (defaults to static/wasm) and the default wasm filename template, for example:
You can customize the directory and filename through output.distPath and output.filename.
This mode is suitable when downstream users do not use another build tool, such as importing the library directly in a Node.js application or loading the ESM output directly in a browser.
In compile mode, Rslib generates runtime code for loading the emitted .wasm file. The loading strategy is derived from Rslib's output.target:
- For web targets, the generated runtime loads
.wasmwithfetch. - For node targets, the generated runtime loads
.wasmfrom the file system with async Node.js APIs.
Preserve mode
In preserve mode, Rslib does not generate WebAssembly loading runtime for direct .wasm imports. Instead, it keeps a real .wasm import in the JavaScript output and emits the binary.
The output layout depends on bundle.
Bundle mode
In bundle mode, source files are bundled into JavaScript chunks, so the .wasm binary is emitted as an asset with a content-hashed filename:
The content-hashed asset layout breaks WebAssembly ESM Integration semantics for .wasm modules that depend on relative module specifiers (for example, some wasm-bindgen outputs whose .wasm file must stay next to its JavaScript glue files). Moving the binary to the asset directory with a hashed name breaks those relative paths. For such modules, use bundleless mode or compile mode.
Bundleless mode
In bundleless mode, Rslib copies the .wasm file to the output using the same source-relative path and original filename:
This layout keeps the .wasm file next to the JavaScript files, which is recommended for WebAssembly packages that rely on relative module specifiers, such as some wasm-bindgen outputs where the .wasm file needs to stay next to JavaScript glue files.
Supported import forms
Rslib supports the following WebAssembly ESM Integration import forms in ESM output.
Static import and export
Use static imports and exports to access the instantiated WebAssembly exports through ESM bindings:
Dynamic import
Dynamic import is also supported:
In preserve mode, Rslib keeps the .wasm module import semantics, while the generated JavaScript may still contain bundler runtime code for JavaScript chunks.
Source phase import
import source is part of WebAssembly ESM Integration. It imports the compiled WebAssembly.Module instead of the instantiated exports.
This is useful when you need to instantiate the module yourself, for example to pass a custom import object:
Dynamic source phase import is also supported through import.source():
In compile mode, Rspack transforms this syntax into JavaScript output, so the final consumer does not need to support source phase imports natively.
In preserve mode, Rslib keeps the source phase import in the output, so the downstream runtime or bundler must support it.
Runtime support:
Bundler support:
TypeScript does not currently parse import source or import.source(). Write source phase imports in JavaScript files or use a toolchain that supports the syntax.
Use wasm-bindgen
wasm-bindgen is a Rust and WebAssembly tool that provides an all-in-one WebAssembly development solution.
When using wasm-bindgen with Rslib, generate the output with --target bundler:
The bundler target generates JavaScript glue files that import the generated .wasm file as an ES module, which matches Rslib's WebAssembly handling model.
A wasm-bindgen output has a relative dependency between the .wasm binary and its JavaScript glue files: the glue imports the .wasm, and the .wasm imports back into the glue. Whether a given Rslib configuration keeps this relationship intact depends on the mode and bundle combination:
In compile mode, Rspack parses the .wasm module and its glue dependencies at build time, so both bundle and bundleless work regardless of layout.
Use bundleless preserve mode when you want to keep the original wasm-bindgen files in the output without generating loading runtime:
Do not use bundle mode preserve for wasm-bindgen outputs. The content-hashed asset layout moves the .wasm file away from its glue files and breaks the relative module specifiers in the generated output. Use compile mode or bundleless preserve mode instead.
TypeScript declarations
TypeScript does not provide built-in module declarations for .wasm files. You can add a declaration file next to the .wasm file using the .d.wasm.ts extension, which requires allowArbitraryExtensions in your tsconfig.json:
Limitations
- Direct WebAssembly ESM Integration imports are only supported for ESM output;
cjs,umd,iife, andmfformats are not supported for direct.wasmimport/export. Whenmodeis set for a non-ESM format, it is ignored and the format falls back to compile behavior.
