12

I wanted a real Rust-to-WASM module doing per-pixel work off the main thread, not a toy that ships 4MB of glue and blocks the UI on load. Most prompts gave me code that assumed a specific bundler and fell apart under Vite.

The prompt below pins the toolchain, forces a narrow FFI boundary (pass a buffer, get a buffer, no fancy structs across the line), and makes the wasm run in a worker with a typed message protocol. It built and ran at interactive speed on a 12MP image.

Anyone got a good way to make the model keep the wasm binary small without me hand-tuning opt-level?

THE PROMPT
Generate a Rust + WebAssembly module for browser image processing plus the TypeScript glue to use it, targeting a Vite app. Keep the boundary tiny and the main thread free.

RUST SIDE (wasm-bindgen):
- Expose one function: `process(input: &[u8], width: u32, height: u32, op: u8) -> Vec<u8>` operating on RGBA. No structs across the FFI boundary, just buffers and primitives.
- Implement ops: 0 grayscale, 1 gaussian blur, 2 sobel edges. No external image crates; write the kernels.
- No panics across the boundary: validate lengths and return the input unchanged on bad input rather than unwrapping.

BUILD: give exact commands using wasm-pack with --target web, and a Cargo.toml with `opt-level = 's'` and `lto = true` for a small binary. State the expected .wasm size ballpark.

WEB SIDE:
- Run the wasm inside a Web Worker. Define a typed message protocol: `{ id, op, width, height, buffer }` in, `{ id, buffer }` out. Transfer the ArrayBuffer, don't copy it.
- A `useImageFilter` hook that posts work and resolves a Promise keyed by id.
- Strict TS, no any.

CONSTRAINT: must build with `wasm-pack build` and the app must import it without a custom bundler plugin. List every file and its path.

1 Answer

5

The transferable ArrayBuffer detail is what makes this actually fast, copying a 12MP buffer per frame would eat all your wins. For the binary size question: add wasm-opt -Oz as a post-build step and tell it to strip the default allocator by using wee_alloc (or just accept the default and lean on -Oz). Also ask it to gate console_error_panic_hook behind a debug feature so it's not in the release wasm.

THE PROMPT
Add a post-build step: run `wasm-opt -Oz` on the output. Put panic-hook and any debug logging behind a cargo feature that's off by default so the release binary stays lean.

Your Answer