JavaScript and WebAssembly

On this page

Use --target js to package a BoxLang application or library for the browser.

ModeCommandStatus
JS module (AOT)--target jsWorks. Ship a compiled app or library as an ES module.
WASI (experimental)--target wasi / --target wasmFor WASI hosts, not browsers. See WASI deployment.
Runtime (source strings)your own crateNeeds a small Rust crate, described below.

Mode 1: JavaScript ES module (AOT)

MatchBox compiles your script to bytecode and writes an ES module that loads a generic MatchBox runtime (.wasm) and the bytecode.

Prerequisites

The wasm-bindgen command line tool, version 0.2.114, must be on PATH, or its location set in WASM_BINDGEN. Without it the command stops with wasm-bindgen not found. Install wasm-bindgen-cli or set WASM_BINDGEN.

Compile

matchbox --target js my_lib.bxs
Standalone JS module produced: ./my_lib.js

The command writes four files next to the script, or next to --output:

FileContents
my_lib.jsThe ES module. The compiled bytecode is embedded in it as a base64 string.
my_lib.wasmThe MatchBox runtime.
my_lib.d.ts, my_lib_bg.wasm.d.tsTypeScript declarations for the runtime.

--output dist/my_lib.js creates dist/ and names the files from the stem my_lib.

Use in HTML

<!DOCTYPE html>
<html>
<head><title>BoxLang App</title></head>
<body>
<script type="module">
    import { greet, calculate } from './my_lib.js';

    const result = await greet("Developer");
    document.body.textContent = result;
</script>
</body>
</html>

Runtime contract

The module starts loading as soon as it is imported. It exports:

  • An async export for each top-level BoxLang function. Use await to collect its result.
  • ready, a promise that resolves when the runtime and bytecode are loaded.
  • BoxLangVM, run_bytecode, initSync and the default init function from the runtime.

In a browser the module also registers window.MatchBox.modules["my_lib"], window.MatchBox.ready("my_lib"), window.MatchBox.State(moduleName, options), and fires a matchbox:ready event on window with detail.module set to the module name.

These modules are intended for browsers. Other JavaScript hosts may need their own WebAssembly loading integration.

Exporting functions

Functions declared at the top level of the script are exported. The exporter collects every top-level function declaration and does not look at access modifiers.

function greet(name) {
    return "Hello, " & name & "!"
}

function calculate(a, b) {
    return a * b
}

Mode 2: WASI (experimental)

Use --target wasi for workloads outside the browser. See WASI deployment for experimental host support.

Native Fusion supports browser builds through --target js; Rust code and dependencies must support that target.


Mode 3: Calling functions and loading bytecode

BoxLangVM is exported by every --target js module. It runs bytecode produced by matchbox --build:

import { ready, BoxLangVM } from './my_lib.js';

await ready;                        // runtime is initialised

const bytes = new Uint8Array(await (await fetch('./other.bxb')).arrayBuffer());

const vm = new BoxLangVM();
vm.load_bytecode(bytes);            // runs the script's top level

// call() is async: it returns a Promise
const message = await vm.call("greet", ["BoxLang"]);
console.log(message);               // Hello, BoxLang!

BoxLangVM exposes load_bytecode(bytes), asynchronous call(name, args), pump() and vm_ptr().

Compiling source strings in the browser

The packaged browser module runs bytecode. To compile source text dynamically, include matchbox_compiler in a custom WebAssembly runtime. This site's playground-runtime/ is an example; see source builds.


JavaScript Interop from BoxLang

When BoxLang code is running inside the browser JS target, it can access a browser bridge through the js global:

// DOM access
title = js.document.title
js.document.getElementById("output").innerText = "Updated by BoxLang"

// Browser APIs
js.alert("Hello!")
js.console.log("Logged from BoxLang")

// Location
url = js.location.href

The important current rule is:

  • Plain JS values cross the boundary as BoxLang values: strings, booleans, null, numbers, arrays, and plain objects.
  • Browser host objects stay as JS handles: DOM nodes, document, window, functions, and other browser-native objects.

That keeps state/data interop predictable while preserving access to real browser objects.

js.* is a browser-only surface. Using it in a native build throws a runtime error.


Serving Locally for Development

Browsers block WASM file loading over file://. Serve your project with any local HTTP server:

npx serve .
# or
python3 -m http.server 8080

Then open http://localhost:8080 in your browser.


Production Deployment

The WASM output files (*.js + *.wasm) can be deployed to any static hosting service:

  • CDN: upload to S3, Cloudflare R2, or a similar object store.
  • Vercel / Netlify: drop the files into your project's output directory.

Ensure your server sets the correct Content-Type for .wasm files:

Content-Type: application/wasm

Most modern hosts handle this automatically.

Edit this page Download Markdown Last updated Oct 27, 2026, 1:45:34 PM Report an issue