Integrating WASM into React with Rust
WebAssembly (or WASM for short) is the new cool kid on the block in the programming world. It lets you write high performant code that runs right in the browser leveraging the power of lower level langauges like C/C++ and Rust.
WASM is by no means a replacement for JS, rather you should use both languages in tandem to build your frameworks. When I set out to start touching WASM, I didn’t find too many guides for properly integrating it into a react application.
The first thing you should do is create a react application. You’ll need node — you can install it using package managers if you’re on linux or mac, or from the install page on windows. I’ll assume you’ve used node from here on out so go watch some videos if you need to familiarize yourself with it and install it.
npx create-react-app my-app
By default once you run the above command, you get a folder structure that looks like:
my-app
|-- README.md
|-- node_modules/
|-- package.json
|-- .gitignore
|-- public/
|-- src/
You’ll need to install cargo to continue from this point on. Check here for how to install cargo on your machine.
Run:
cargo new webassembly
Now you’ll have a directory with a cargo.toml file and a src folder with the file main.rs
Edit your cargo.toml file to look similar to mine:
[package]
name = "WebAssembly"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2.86"
Now we have added the wasm-bindgen library to our project. This will let us compile our rust code to WASM.
Rename main.rs to lib.rs (we’re making a library for JS, not an standalone rust application) and lets make an example function.
use wasm_bindgen::prelude::*
#[wasm_bindgen]
pub fn add_numbers(a: i32, b:i32) -> i32 {
a + b
}
Now we have a basic function that we can call from JS. wasm_bindgen::prelude::* is a convention among Rust programmers to let you quickly import all the necessary aspects of a library needed to use their library.
#[wasm_bindgen] tells wasm_bindgen to generate some wrapper code in JS so we can access this function in our react application.
To compile run the command:
wasm-pack build — target web — out-dir ../public/pkg
This will create a folder under my-app/public called pkg that contains our needed “glue code”.
I would cd into node_modules add a symlink to pkg to make importing a little bit easier:
ln -s ../public/pkg pkg
Now lets call this add_numbers from a react component:
import init, { add_numbers } from "pkg/WebAssembly";
const testComponent = () => {
const [sum, setSum] = useState(0)
//load WASM
async function loadWasm() {
const module = await init();
// Access the exported function
const result = add_numbers(2, 3);
setSum(result);
console.log(result);
}
loadWasm();
return (
<>
<p>{sum}</>
</>
);
}
You should be able to see the number 5 in your console as well as in your testComponent.
I hope this helps others get started using WASM in their react application! This is insanely cool technology and I hope more people play around with it!