Skip to main content

WebAssembly

Xi compiles to portable C99 and then invokes a C compiler — so targeting the web is a matter of swapping that compiler for Emscripten. xc --target wasm <source.xi> builds the same program and runtime to WebAssembly instead of a native binary; codegen is unchanged.

$ xc --target wasm examples/wasm_demo.xi
xc: built WebAssembly build/wasm_demo.{html,js,wasm}
xc: serve it, e.g. python3 -m http.server -d build then open wasm_demo.html

This emits three files in $XC_OUT (default build/):

FilePurpose
<name>.wasmthe compiled module
<name>.jsthe loader/glue that instantiates the module
<name>.htmla ready-to-open page that runs entry main and shows output

stdout/stderr are wired to the page console (and the browser devtools console). You can also run the build headless under Node — node build/<name>.js — which is handy in CI.

Requirements

Emscripten must be on your PATH:

$ brew install emscripten # macOS
# or follow https://emscripten.org/docs/getting_started/downloads.html
$ emcc --version

If emcc is missing, xc --target wasm prints an install hint and stops; the native build needs only cc and is unaffected.

Serving the page

Browsers won't instantiate a .wasm over file://, so serve the directory:

$ python3 -m http.server -d build
# open http://localhost:8000/wasm_demo.html

What runs in the browser

The build is single-threaded and runs in the browser sandbox, so portability follows the platform — not Xi:

WorksNotes
Pure computation, strings, arrays, mathidentical to native
system.stdout / system.stderrrouted to the page/devtools console
File I/O (std/fs)operates on Emscripten's in-memory virtual filesystem, not the user's disk
Randomnessbacked by the browser crypto API
Limited / unavailableWhy
TCP servers & raw sockets (std/net, std/web server)the browser has no listening sockets; client networking must go through fetch/WebSockets
Spawning processes / run_commandno process model in the sandbox
TLS / HTTP/2 native links (XC_TLS, XC_HTTP2)host libraries (OpenSSL, nghttp2) aren't linked into the WASM build
Native FFI (extern "C" linking -l<lib>)host shared libraries don't exist in the sandbox; a library must itself be compiled to WASM

A good rule of thumb: anything that is pure logic or talks only to stdout ports cleanly today. Anything that reaches the operating system (sockets, processes, real files) needs a browser-shaped replacement.

Calling Xi from JavaScript

The current target runs a whole program (entry main) end to end. Exporting individual Xi functions to call from JavaScript — with value marshaling across the JS↔WASM boundary — is a planned next step and not yet wired up.

See also