WebAssembly (WASM) Build

Why would you do that?

There is already a fast and powerful scripting language that integrates nicely with WASM – JavaScript.

Anyhow, do it because you can!

It is possible to use Rhai when compiling to WebAssembly (WASM).

This yields a scripting engine (and language) that can be run in a standard web browser, among other places.

Unavailable features

When building for WASM, certain features will not be available, such as the script file API’s and loading modules from external script files.

Sample

Check out the Online Playground project which is driven by a Rhai Engine compiled into WASM.

JavaScript Interop

Specify either of the wasm-bindgen or stdweb features when building for WASM. This selects the appropriate JavaScript interop layer to use.

It is still possible to compile for WASM without either wasm-bindgen or stdweb, but then the interop code must be explicitly provided.

Size

Also look into minimal builds to reduce generated WASM size.

As of this version, a typical, full-featured Rhai scripting engine compiles to a single WASM file less than 300KB gzipped.

When excluding features that are marginal in WASM environment, the gzipped payload can be further shrunk to 160KB.

The following standard packages, when excluded, provide the corresponding size savings:

PackageWASM size saving
CorePackage18 KB
BitFieldPackage1 KB
LogicPackage< 1 KB
BasicMathPackage1 KB
BasicArrayPackage15 KB
BasicBlobPackage7 KB
BasicMapPackage4 KB
MoreStringPackage34 KB

Speed

In benchmark tests, a WASM build runs scripts roughly 1.7-2.2x slower than a native optimized release build.

Common Features

Some Rhai functionalities are not necessary in a WASM environment, so the following features are typically used for a WASM build:

FeatureDescription
wasm-bindgen or stdwebuse wasm-bindgen or stdweb as the JavaScript interop layer, omit if using custom interop code
uncheckedwhen a WASM module panics, it doesn’t crash the entire web app; however this also disables maximum number of operations and progress tracking so a script can still run indefinitely – the web app must terminate it itself
only_i32WASM supports 32-bit and 64-bit integers, but most scripts will only need 32-bit
f32_floatWASM supports 32-bit single-precision and 64-bit double-precision floating-point numbers, but single-precision is usually fine for most uses
no_modulea WASM module cannot load modules from the file system, so usually this is not needed, but the savings are minimal; alternatively, a custom module resolver can be provided that loads other Rhai scripts

The following features are typically not used because they don’t make sense in a WASM build:

FeatureWhy unnecessary
syncWASM is single-threaded
no_stdstd lib works fine with WASM
metadataWASM usually doesn’t need access to Rhai functions metadata
internalsWASM usually doesn’t need to access Rhai internal data structures, unless you are walking the AST
debuggingunless debugging is needed