๐Ÿ”ท Core trusted

boxlang-wasm-in-the-browser

Use this skill when compiling BoxLang to WebAssembly or JavaScript ES modules for use in web browsers and Node.js using MatchBox's --target js or --target wasm flags, integrating with HTML pages, bundlers (Webpack/Vite), and Node.js projects.

$ npx skills add ortus-boxlang/skills/boxlang-developer/running-boxlang/wasm-in-the-browser
$ coldbox ai skills install ortus-boxlang/skills/boxlang-developer/running-boxlang/wasm-in-the-browser
๐Ÿ”— https://skills.boxlang.io/skills/raw/ortus-boxlang/skills/boxlang-developer~running-boxlang~wasm-in-the-browser

BoxLang WASM in the Browser

Overview

MatchBox can compile BoxLang source to browser-compatible output via two modes:

ModeFlagOutputBest For
ES Module (recommended)--target js.js + .wasmBrowsers, Node.js, bundlers
Raw WASM--target wasm.wasmCustom loaders, advanced bundling

All top-level BoxLang functions are automatically exported, regardless of access modifier.


matchbox --target js my_lib.bxs
# Output: my_lib.js + my_lib.wasm

The generated .js file is an ES module wrapper. The .wasm file is loaded automatically.

Browser Usage

<!DOCTYPE html>
<html>
<head>
    <title>BoxLang in the Browser</title>
</head>
<body>
    <script type="module">
        import { greet, calculateTotal } from './my_lib.js'

        const message = greet("World")
        document.getElementById("output").textContent = message

        const total = calculateTotal([ 10.99, 5.49, 3.00 ])
        console.log("Total:", total)
    </script>

    <div id="output"></div>
</body>
</html>

BoxLang source (my_lib.bxs)

// All top-level functions are exported automatically
function greet( name ) {
    return "Hello, " & name & "!"
}

function calculateTotal( prices ) {
    return prices.reduce( ( sum, price ) -> sum + price, 0 )
}

Node.js Usage

// node-app.mjs
import { greet, calculateTotal } from './my_lib.js'

console.log( greet( "Node.js" ) )
console.log( calculateTotal([ 10.99, 5.49, 3.00 ]) )
node node-app.mjs

Mode 2: --target wasm โ€” Raw WASM

matchbox --target wasm my_lib.bxs
# Output: my_lib.wasm

Use this when you need manual control over WASM loading, or integration with Webpack/Vite:

// Manual loading
const { instance } = await WebAssembly.instantiateStreaming(
    fetch('/my_lib.wasm'),
    {}
)
const { greet } = instance.exports

Vite Integration

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
    assetsInclude: ['**/*.wasm'],
    plugins: []
})
// main.js โ€” with Vite WASM handling
import wasmUrl from './my_lib.wasm?url'

const response = await fetch(wasmUrl)
const { instance } = await WebAssembly.instantiateStreaming(response)
const { greet } = instance.exports

Function Export Rules

  • All top-level functions are exported automatically (no public annotation needed)
  • Functions defined inside class bodies are NOT exported
  • Keep exported BoxLang functions at the top level of the .bxs file
// โœ… Exported โ€” top-level function
function add( a, b ) {
    return a + b
}

// โœ… Exported โ€” top-level function
function formatCurrency( amount, currency = "USD" ) {
    return currency & " " & numberFormat( amount, "2" )
}

// โŒ NOT exported โ€” inside a class
class MyLib {
    function helper() { ... }
}

Browser Compatibility

BrowserES Module WASM Support
Chrome 61+โœ…
Firefox 60+โœ…
Safari 14.1+โœ…
Edge 79+โœ…
Node.js 14+โœ…

Bundler Integration

Webpack 5

// webpack.config.js
module.exports = {
    experiments: {
        asyncWebAssembly: true
    }
}
// app.js
const myLib = await import('./my_lib.js')
myLib.greet("Webpack")

Vite + ES Module

# Place my_lib.js + my_lib.wasm in /public or /src/assets
# Import as ES module (no special config needed for --target js output)
import { greet } from '/my_lib.js'
greet("Vite")

Development Workflow

# 1. Write BoxLang logic
cat > utils.bxs << 'EOF'
function slugify( text ) {
    return text.lCase().reReplace( "[^a-z0-9]+", "-", "all" ).trim( "-" )
}

function truncate( text, maxLen = 100 ) {
    return text.len() > maxLen ? text.left( maxLen ) & "..." : text
}
EOF

# 2. Compile to ES module
matchbox --target js utils.bxs

# 3. Serve (for browser testing โ€” WASM requires HTTP, not file://)
npx serve .

# 4. Import in your app

Important: WASM files must be served over HTTP (not file://). Use a local dev server like npx serve, Vite, or a browser extension during development.


Checklist

  •  Use --target js for browser and Node.js integration (simpler than raw WASM)
  •  Keep exported functions at the top level of the .bxs file
  •  Serve via HTTP (not file://) โ€” browsers block WASM from file:// origins
  •  For bundlers (Vite/Webpack), copy both .js and .wasm output files together
  •  Use --target wasm only when you need manual loader control or advanced bundling
  •  Test in Node.js first for faster iteration before testing in the browser