The Pattern
A Rust crate compiled to a 20 KB wasm module, vendored into the repo and loaded with zero Vite plugins. The dev container never needs a Rust toolchain: a throwaway builder container compiles the crate, and the generated glue and binary are committed like any other source.
The kernel
Pixels live in wasm linear memory. JS writes them through a view once, filter calls cross the boundary with two scalars, and a vitest parity gate keeps the Rust and JS implementations byte-identical.
#[wasm_bindgen]
pub struct PixelKernel {
width: u32,
height: u32,
pixels: Vec<u8>, // JS writes through a view over pixels_ptr() — once
scratch: Vec<u8>, // preallocated: no filter call may grow wasm memory
}
#[wasm_bindgen]
impl PixelKernel {
/// Filter calls cross the boundary with two scalars, never with the frame.
pub fn box_blur(&mut self, radius: u32) { /* (2r+1)² taps per pixel */ }
pub fn grayscale(&mut self) { /* Rec.601 integer luma */ }
}The build
One host-side script, one ephemeral Rust container, artifacts committed. Reproducibility is pinned by a digest-pinned builder image, rust-toolchain.toml and Cargo.lock — and a committed build manifest turns the gate red if sources and artifacts drift apart.
# scripts/wasm/build.sh — the v10r container stays Rust-free
RUST_IMAGE="docker.io/library/rust:1.97-slim@sha256:8e8cf8…" # digest-pinned
podman run --rm -v "$PWD:/work" -w /work/crates/kernel "$RUST_IMAGE" bash -c '
cargo build --release --target wasm32-unknown-unknown
wasm-bindgen --target web --out-dir /work/src/lib/wasm/kernel \
target/wasm32-unknown-unknown/release/v10r_kernel.wasm'
# kernel.js + kernel_bg.wasm (+ .d.ts) are COMMITTED, plus build-manifest.json:
# sha256 of sources and artifacts — a vitest gate recomputes them, so a Rust
# edit without a rebuild goes red. `bun run validate` never needs Rust.The loader
?url plus an explicit init call sidesteps every known dev-vs-build wasm divergence in Vite and SvelteKit — no wasm plugin, no top-level await, nothing executed during SSR.
import wasmUrl from './kernel/kernel_bg.wasm?url';
let ready: Promise<Kernel> | null = null;
export function loadKernel(): Promise<Kernel> {
// ?url + explicit init: no Vite wasm plugins, no top-level await (broken
// under Svelte 5 — sveltejs/kit#13015), nothing executed during SSR, and
// the binary ships as a hashed immutable asset.
if (!ready) {
ready = import('./kernel/kernel.js').then(async (mod) => {
const out = await mod.default({ module_or_path: wasmUrl });
return { mod, memory: out.memory };
});
}
return ready;
}