Overview
What is rust-wasmpack-loader?β
rust-wasmpack-loader is a WebAssembly loader that lets you import .rs files directly in JavaScript and TypeScript. You import a Rust file the same way you import any module, and the loader compiles it to WebAssembly behind the scenes.
How it worksβ
When you import a .rs file, the loader:
- Detects the
.rsfile in your project - Finds the nearest
Cargo.toml - Compiles the Rust code to WebAssembly with
wasm-pack - Generates JavaScript bindings with
wasm-bindgen - Wires the compiled module into your bundle
Architectureβ
Key benefitsβ
- Import
.rsfiles like any other module, with no separate build step to wire up - Hot reload during development
- Typed
.rsimports: an ambient floor for valid imports, generated.d.rs.tssidecars for the exact#[wasm_bindgen]signatures, and an editor Language Service plugin for live types - Webpack 5+ with explicit targets (web, node)
- Rspack through the same Webpack-compatible loader
- Bun runtime support
- esbuild plugin for bundling on Node.js or the browser
- Rollup plugin for Rollup-based pipelines
- Vite plugin that produces SSR (
node) and client (web) output from a single.rsimport - Next.js helper (
withRustWasm) so one.rsfile works from Server Components, Client Components, and Edge routes (App Router)
Use casesβ
The loader fits work where Rust earns its keep:
- Mathematical computation (cryptography, image processing, algorithms)
- Large-scale data processing (parsing, transformation, validation)
- Game engines and graphics programming
- Performance-critical libraries
- Migrating existing C/C++ code to the web
Concrete examples:
- Image filters and manipulation
- Cryptocurrency mining or validation (please don't do this in a browser)
- Scientific simulation
- Audio and video processing
- Machine learning inference
- Compression algorithms
Supported targetsβ
| Target | Webpack | Rspack | Bun | esbuild | Rollup | Vite | Next.js |
|---|---|---|---|---|---|---|---|
web | β | β | β | β | β | β | β |
node | β | β | β | β | β | β | β |
node-async | β | β | β | β | β | β | β |
electron | β | β | β | β | β | β | β |
Rspack reuses the Webpack loader context, so the loader works with it through the same configuration.
Electron's webpack targets map onto the same two strategies: electron-main and electron-preload use the node
strategy, electron-renderer uses web, and both inline the wasm bytes. webpack normalizes versioned targets such as
electron20-main down to these names before the loader sees them, and Rspack resolves them the same way, so the loader
works under both. See the Electron example for the two-config setup.
Next.js uses the loader through the withRustWasm helper: the server build runs node, the client build runs web, and
both inline the wasm bytes. Edge routes work too, through a separate module delivery that ships the wasm as a
pre-compiled WebAssembly.Module (the one form the Edge runtime can instantiate). The helper wires all of this into both
bundlers, so the wrapped config builds under Turbopack (next build, the Next.js 16 default) and webpack (next build --webpack) alike. The asset-emitting modes (web.asyncLoading, node.bundle: false) still need emitFile, which
Turbopack does not expose, so the helper leaves them out of the Next path.
Comparison with alternativesβ
Legend:
- β Full support - works out of the box
- β οΈ Partial support - works with extra configuration
- π€ Manual setup - needs manual steps to enable
- β No support - not available
- π’ Good - smooth experience
- π‘ Medium - workable with some effort
- π΄ Poor - significant friction
| Feature | rust-wasmpack-loader | Manual wasm-pack | @wasm-tool/wasm-pack-plugin | vite-plugin-wasm | Rollup WASM | esbuild WASM | Raw WASM imports |
|---|---|---|---|---|---|---|---|
| Direct .rs imports | β | β | β | β | β | β | β |
| Auto Cargo.toml detection | β | β | π€ | β | β | β | β |
| Hot reload support | β | β | β | β | β οΈ | β | β |
| Bun runtime support | β | π€ | β | β | β | π€ | π€ |
| Webpack integration | β | β | β | β | β | β | β οΈ |
| Vite/Rollup integration | β | β | β | β | β | β | β οΈ |
| esbuild integration | β | β | β | β | β | β | β οΈ |
| TypeScript bindings | β | β | β | β | β | β | β |
| Zero configuration | β | β | β | β | β | β | β |
| Async WASM loading | β | β | β | β | β | β | β |
| Bundle size optimization | β | β οΈ | β οΈ | β | β | β | β οΈ |
| Node.js target support | β | β | β | β οΈ | β | β | β |
| Web target support | β | β | β | β | β | β | β |
| Learning curve | π’ Easy | π΄ Hard | π‘ Medium | π‘ Medium | π‘ Medium | π‘ Medium | π΄ Hard |
| Maintenance status | π’ Active | π’ Active | π‘ Limited | π’ Active | π’ Active | π’ Active | N/A |
What sets rust-wasmpack-loader apart:
- The only loader with direct
.rsfile imports and no build configuration - Native Bun runtime support, which no other option in this list provides
- Automatic
Cargo.tomldiscovery up the directory tree - Zero configuration for basic usage
- One package covering Webpack, Rspack, Bun, esbuild, Rollup, Vite, and Next.js
- The only one that compiles the same
.rsimport to SSR (node) and client (web) output in Vite automatically
How the alternatives compare:
- Manual wasm-pack: separate build steps and manual integration
- @wasm-tool/wasm-pack-plugin: more mature but Webpack-only, less automated, and needs explicit configuration
- vite-plugin-wasm: Vite-specific, a different ecosystem
- Rollup and esbuild WASM: expect pre-compiled WASM files
- Raw WASM imports: no build automation, and you write the TypeScript bindings yourself