A SpiderMonkey-based JS runtime on WebAssembly
A Bytecode Alliance project
Building | Adopters | Documentation | Chat
StarlingMonkey is a SpiderMonkey based JS runtime optimized for use in WebAssembly Components. StarlingMonkey's core builtins target WASI 0.2.0 to support a Component Model based event loop and standards-compliant implementations of key web builtins, including the fetch API, WHATWG Streams, text encoding, and others. To support tailoring for specific use cases, it's designed to be highly modular, and can be readily extended with custom builtins and host APIs.
StarlingMonkey is used in production for Fastly's JS Compute platform, and Fermyon's Spin JS SDK. See the ADOPTERS file for more details.
For comprehensive documentation, visit our Documentation Site.
The runtime's build is managed by cmake, which also takes care of downloading the build dependencies. To properly manage the Rust toolchain, the build script expects rustup to be installed in the system.
With sufficiently new versions of cmake
and rustup
installed, the build process is as follows:
- Clone the repo
git clone https://github.com/bytecodealliance/StarlingMonkey
cd StarlingMonkey
- Run the configuration script
For a release configuration, run
cmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release
For a debug configuration, run
cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug
- Build the runtime
The build system provides two targets for the runtime: starling-raw.wasm
and starling.wasm
. The former is a raw WebAssembly core module that can be used to build a WebAssembly Component, while the latter is the final componentized runtime that can be used directly with a WebAssembly Component-aware runtime like wasmtime.
A key difference is that starling.wasm
can only be used for runtime-evaluation of JavaScript code,
while starling-raw.wasm
can be used to build a WebAssembly Component that is specialized for a specific
JavaScript application, and as a result has much faster startup times.
The following command will build the starling.wasm
runtime module in the cmake-build-release
directory:
# Use cmake-build-debug for the debug build
cmake --build cmake-build-release -t starling --parallel $(nproc)
The resulting runtime can be used to load and evaluate JS code dynamically:
wasmtime -S http cmake-build-release/starling.wasm -e "console.log('hello world')"
# or, to load a file:
wasmtime -S http --dir . starling.wasm index.js
To create a specialized version of the runtime, first build a raw, unspecialized core wasm version of StarlingMonkey:
# Use cmake-build-debug for the debug build
cmake --build cmake-build-release -t starling-raw.wasm --parallel $(nproc)
Then, the starling-raw.wasm
module can be turned into a component specialized for your code with the following command:
cd cmake-build-release
./componentize.sh index.js -o index.wasm
This mode currently only supports the creation of HTTP server components, which means that the index.js
file must register a fetch
event handler. For example, your index.js
could contain the following code:
addEventListener('fetch', event => {
event.respondWith(new Response('Hello, world!'));
});
Componentizing this code like above allows running it like this:
wasmtime serve -S cli --dir . index.wasm