Skip to main content

Rollup example

This example shows how to use rust-wasmpack-loader with Rollup. The loader ships a Rollup plugin, so you import .rs files directly from your bundle.

The plugin inlines the compiled WebAssembly as bytes into the generated JavaScript, so there is no extra asset to handle. Rollup has no platform concept of its own, so you choose the build strategy through the plugin's target option: web (the default) or node. This example targets Node.js.

Because Vite plugins are a superset of Rollup plugins, the same plugin works inside a Vite config.

Project structure​

rollup-example/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ index.js # Entry point importing the .rs module
β”‚ β”œβ”€β”€ index.test.js # Test entry using node:test
β”‚ └── lib.rs # Rust WebAssembly code
β”œβ”€β”€ dist/ # Build output
β”œβ”€β”€ rollup.config.mjs # Rollup configuration wiring up the plugin
β”œβ”€β”€ Cargo.toml # Rust configuration
└── package.json # Dependencies and scripts

Setup​

1. Initialize the project​

mkdir my-rollup-wasm-app
cd my-rollup-wasm-app
npm init -y

2. Install dependencies​

npm install --save-dev rust-wasmpack-loader rollup

3. Create Cargo.toml​

Cargo.toml
[package]
name = "rollup-wasm-example"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.95"

4. Create the Rust code​

src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}

#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}! Greetings from Rust via Rollup!", name)
}

5. Create the entry point​

Import the .rs file like any other module and call its exports.

src/index.js
import wasmModule from "./lib.rs";

console.log(wasmModule.greet("Rollup Developer"));
console.log(`fibonacci(10) = ${wasmModule.fibonacci(10)}`);

6. Create the Rollup config​

rollup.config.mjs
import rustWasmLoader from "rust-wasmpack-loader";

export default {
input: "src/index.js",
output: {
dir: "dist",
format: "esm",
},
external: (id) => id.startsWith("node:"),
plugins: [rustWasmLoader.rollup({ target: "node", logLevel: "info" })],
};

For browser output, set target: "web" (the default). The plugin then builds the web strategy and inlines the WebAssembly into the bundle.

7. Update package.json​

package.json
{
...,
"type": "module",
"scripts": {
"build": "rollup -c rollup.config.mjs",
"start": "rollup -c rollup.config.mjs && node dist/index.js"
},
...
}

Running the example​

# Build the bundle
npm run build

# Build and run it
npm start

Plugin options​

The Rollup plugin accepts a target (since Rollup has no platform of its own) plus the shared logLevel option:

rustWasmLoader.rollup({
target: "web", // "web" | "node" (default "web")
logLevel: "info", // "verbose" | "info" | "warn" | "error" | "quiet"
});

Using it with Vite​

Vite builds on Rollup, so this plugin works inside a Vite config. For Vite, prefer the dedicated rustWasmLoader.vite plugin: it picks the node strategy for SSR and the web strategy for the client automatically, where this Rollup plugin uses a single fixed target. See the Vite example for the full setup.

vite.config.mjs
import { defineConfig } from "vite";
import rustWasmLoader from "rust-wasmpack-loader";

export default defineConfig({
plugins: [rustWasmLoader.vite()],
});

Inline delivery

The Rollup plugin currently inlines the .wasm bytes into the generated JavaScript, so there is no separate asset to copy or serve and no extra configuration. Separate-asset delivery may arrive as a later enhancement.