MiniWASM - A minimalist Rust WebAssembly project template
This is a minimal Rust-powered WebAssembly application template. It was designed to showcase what must be done to get Rust-powered WebAssembly going with only a small amount of code, while still providing useful tools, such as integration with
How to build?
The easiest way is to install Docker on your system and run the
docker-shell.sh script. This script builds a Docker image containing Rust, the wasm32-unknown-unknown target, and a couple of dependencies for optimizing the generated
After building the Docker image the script then launches a container with that image, giving you a shell with a proper build environment. Alternatively you can just install Rust and the
wasm32 target on your host machine, and also install
Either way, after opening a shell with a build environment, you can just run the
build.sh script. This builds the
miniwasm.wasm file and runs it through the optimizer to reduce the file size.
Now that you have the compiled WebAssembly file you can run the
serve.sh script. This runs a web server in the current working directory (thanks to Python). You can then go to
http://localhost:8000/ to view the application. Open the console to see the log messages that the WebAssembly produces.
Why not wasm-bindgen or wasm-pack?
Another reason why you might want to use MiniWASM as a starting point is that you want to build something small and don't want to depend on wasm-pack's NPM packages.
This application template should be compatible with all modern browsers. However, it has only been tested with Chrome 88 and Safari 14. It will probably work fine in Firefox too though.
This project consists of two components:
- A Rust file serving as the entry point for the WebAssembly application.
The Rust WebAssembly application
The Rust WebAssembly application is a single-file crate that performs a few functions:
It sets up
wee_allocas the memory allocator.
console.logand one for
console.error) and calling them with the address and length of a
It defines a struct that holds the application's global state and stores this in a cell in thread local storage.
It defines functions that act as a bridge between the WebAssembly module's external interface and the application struct.
Instantiating a WebAssembly module is easy. We just have to fetch the
.wasm file and pass its contents into
To get logging to work we need to do a little bit more though. When instantiating the WebAssembly module we provide an import descriptor that exposes
console.error. We can't expose those functions directly though, because WebAssembly's calling convention only allows us to use primitive types as arguments and return values. Therefore we wrap the logging functions with a function that takes the location of a string slice and extracts the bytes from the WebAssembly application's
Copyright 2021 Emil Loer.
This project is licensed under the MIT license. A copy of the license can be found in the project repository.