Ever wonder how to integrate WebAssembly (WASM) modules built with Rust into a Remix application? This post covers setting up the project, creating a Rust WASM module, and integrating it into a Remix app. The example uses a Game of Life implementation to demonstrate the process.
This is a guide on how to integrate a wasm module built from rust into a remix app. All of the code for this example can be found at 🔗 https://github.com/DarkViolet-ai/remix-wasm
Make sure your rust installation is up to date with rustup.
rustup update
Start by creating the new remix project
npx create-remix@latest --app-name=remix-wasm
npm install vite-plugin-wasm
You are now ready to start building your wasm module.
Create a new rust project
cargo new rust-wasm-lib --lib
Edit your cargo toml file to include whatever you need for your wasm module. For the game of life example, the cargo.toml will look like this:
[package]
name = "rust-wasm-lib"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = { version = "0.2.93", features = ["serde-serialize"] }
wasm-bindgen-futures = "0.4.33"
web-sys = { version = "0.3.70", features = [
"Window", "Document", "HtmlCanvasElement", "CanvasRenderingContext2d",
"AudioContext", "AnalyserNode", "MediaDevices", "Navigator",
"MediaStreamConstraints", "MediaStream", "MediaStreamAudioSourceNode"
] }
js-sys = "0.3.70"
plotters = "0.3.5"
plotters-canvas = "0.3.0"
wee_alloc = "0.4.5"
rand = "0.8.5"
getrandom = { version = "0.2", features = ["js"] }
[profile.release]
panic = "abort"
For this example, I started with an implementation of the game of life. This code was generated in collaboration with Claude Sonnet 3.5 using the cursor IDE. I won't paste all of that code in here, but you can review it in the github repo. This is a simple implementation whose main purpose is to give us some eye candy to work with in the remix app.
"scripts": {
"build:wasm": "cd rust-wasm-lib && wasm-pack build --target web",
"build": "npm run build:wasm && remix vite:build",
"dev": "npm run build:wasm && remix vite:dev",
}
Test out the build of the wasm module by running:
npm run build:wasm
All that is left now is to make the component that will host the wasm module.
Note that the build process will create a pkg folder with the wasm module and the js wrapper code. We only need to import the wrapper code into our project.
🔗 This is implemented in the game-of-life route
import initWasm, { Universe } from "../../rust-wasm-lib/pkg/rust_wasm_lib";
From there, we just call the functions from the wasm module. In this case, we pass a canvas element id to the wasm module and it will draw the game of life to the canvas. All of the graphics processing and game logic is handled in the wasm module.
In the repo, we also have an example of a breakout game, also written entirely by AI (Sonnet 3.5 and Cursor IDE).
This project was one of my first attempts to use Cursor Composer to write the entire codebase according to my normal language specifications. I think having the ability to insert wasm modules into remix is a powerful tool that can enable a lot of new functionality in web apps. I used AI to teach me how to get this done, and it worked better than I expected. Now I have a new skill under my belt, and I hope you do too.