--- name: boxlang-runtime-wasm-in-the-browser description: "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." --- # BoxLang WASM in the Browser > BoxLang is the AI-native software productivity platform for building, modernizing and running applications, with developers and AI agents working together. ## Overview MatchBox can compile BoxLang source to browser-compatible output via two modes: | Mode | Flag | Output | Best For | |------|------|--------|---------| | ES Module (recommended) | `--target js` | `.js` + `.wasm` | Browsers, Node.js, bundlers | | Raw WASM | `--target wasm` | `.wasm` | Custom loaders, advanced bundling | All top-level BoxLang functions are automatically exported, regardless of access modifier. --- ## Mode 1: `--target js` — ES Module (Recommended) ```bash 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 ```html BoxLang in the Browser
``` ### BoxLang source (`my_lib.bxs`) ```js // 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 ```js // node-app.mjs import { greet, calculateTotal } from './my_lib.js' console.log( greet( "Node.js" ) ) console.log( calculateTotal([ 10.99, 5.49, 3.00 ]) ) ``` ```bash node node-app.mjs ``` --- ## Mode 2: `--target wasm` — Raw WASM ```bash 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: ```js // Manual loading const { instance } = await WebAssembly.instantiateStreaming( fetch('/my_lib.wasm'), {} ) const { greet } = instance.exports ``` ### Vite Integration ```js // vite.config.js import { defineConfig } from 'vite' export default defineConfig({ assetsInclude: ['**/*.wasm'], plugins: [] }) ``` ```js // 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 ```js // ✅ 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 | Browser | ES Module WASM Support | |---------|----------------------| | Chrome 61+ | ✅ | | Firefox 60+ | ✅ | | Safari 14.1+ | ✅ | | Edge 79+ | ✅ | | Node.js 14+ | ✅ | --- ## Bundler Integration ### Webpack 5 ```js // webpack.config.js module.exports = { experiments: { asyncWebAssembly: true } } ``` ```js // app.js const myLib = await import('./my_lib.js') myLib.greet("Webpack") ``` ### Vite + ES Module ```bash # Place my_lib.js + my_lib.wasm in /public or /src/assets # Import as ES module (no special config needed for --target js output) ``` ```js import { greet } from '/my_lib.js' greet("Vite") ``` --- ## Development Workflow ```bash # 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