We will describe how to implement simple modules and compile them to WebAssembly. Such module then can be used seamlessly in Vanilla JavaScript web application or React.js web application compiled as JavaScript modules 1 and published at npm 2 as npm package.
Rust to WebAssembly
First we prepare ourselves by installing Rust and Cargo to Unix system.
curl https://sh.rustup.rs -sSf | shThen we install wasm-pack for creating modularized Wasm binaries.
cargo install wasm-packOnce we are ready we go to /modules folder and instantiate new one. We find it in /modules/pwnrusthellowasm.
cargo new --lib pwnrusthellowasmWe code our desired functionality in the Rust module.
Distribute Rust module as npm package
Rust to Wasm compilation can be carried out to accomodate npm module format as well. We have to set target to --target bundler. To prepare, or expose our prepared packed functionality run following commands in the appopriate module folder. Then package.json with appropriate entrypoint to pwnrusthellowasm.js is generated for us.
Rust to Wasm overview
Rust3 is prepared to run in the web browser. There are several key takeways and tools making it possible.
- WebAssembly Core Specification (2019) 4 bringing
Wasmruntime to browser standard. wasm-packtool for compiling code to WebAssembly.wasm-bindgento communicate between Rust and JavaScript.
Then Rust lib -> ES6 code / ES6 module, Cargo.toml -> package.json, + js wrapper.
Our final code, js wrapper and wasm is then found in /pkg directory.
Wasm module in React.js (framework Next.js)
Demonstrational snippet usage on how to load npm package (acutal prepared and bundled Wasm binary) and use module's functions.
// Define a type for the Rust module
type IRustModule = {
greet: (message: string) => null;
greetStatic: () => string;
};
export default function Home() {
const [count, setCount] = useState(0)
const [rustModule, setRustModule] = useState<IRustModule | null>(null);
useEffect(() => {
// Dynamically import the Rust Wasm module
import('pwnrusthellowasm').then((module: any) => {
setRustModule(module);
});
}, []);
const handleGreetClick = () => {
if (rustModule) {
const { greet } = rustModule;
const result = greet('Calling Rust function greet(&str), popping back JS alert from Rust.');
console.log(result);
}
};
const handleGreetStaticClick = () => {
if (rustModule) {
const { greetStatic } = rustModule;
const result = greetStatic();
console.log(result);
}
};
return (
<>
{/*...*/}
</>
)
}Code of described project
Check out the code project. Rust code from the repository is compiled using Makefile, then uploaded to npm registry. It is then included as project dependency in package.json of demo project, which is attached with simple usage.
- Rust code https://github.com/KlosStepan/Rust-to-Wasm-packages
- Application running our npm package https://github.com/KlosStepan/Next-ft-Wasm