WebUI WebAssembly #

WebUI provides browser-ready WebAssembly bindings through wasm-bindgen. The bindings are built as three variants so you can choose only the parser, only the handler, or the combined playground bundle.

Variants #

VariantImport pathExportsUse when
Handlerwasm/handler/webui_wasm_handler.jsrender, render_partial, protocol_tokens, render_component_templatesYou already have protocol bytes and only need rendering
Parserwasm/parser/webui_wasm_parser.jsbuild_protocolYou need to compile virtual browser files into protocol bytes
Allwasm/all/webui_wasm_all.jsParser and handler exportsYou need both sides in one module, such as the docs playground

The handler-only bundle excludes webui-parser, and the parser-only bundle excludes webui-handler. The combined bundle keeps the previous playground behavior.

Building the WASM bundles #

cargo xtask build-wasm

The output is generated under docs/.webui-press/public/wasm/ for the documentation playground and release staging. Rebuild it when Rust code in webui-wasm, webui-parser, webui-handler, or webui-protocol changes.

Handler-only API #

Use the handler bundle when the protocol was built elsewhere and loaded as protobuf bytes in the browser.

import init, { render } from './wasm/handler/webui_wasm_handler.js';

await init();

const protocolBytes = new Uint8Array(await (await fetch('/protocol.bin')).arrayBuffer());
const stateJson = '{"title": "Hello"}';
let html = '';

render(protocolBytes, stateJson, (chunk) => {
  html += chunk;
}, { entry: 'index.html', requestPath: '/', plugin: 'webui' });

#

Render a pre-built WebUI protocol with state data.

ParameterTypeDescription
protocolBytesUint8ArrayProtobuf-serialized WebUIProtocol, such as protocol.bin
stateJsonstringJSON string with render state
onChunk(html: string) => voidCallback invoked with each rendered HTML fragment
options.entrystring | undefinedEntry fragment ID, defaults to index.html
options.requestPathstring | undefinedRequest path used for route matching, defaults to /
options.pluginstring | undefinedHandler plugin name, such as webui, fast-v3, fast-v2, or fast

Returns nothing on success. Throws on protocol, state, plugin, callback, or render errors.

For a complete static/CDN service worker example using this callback to write a ReadableStream and mirror --theme token injection in the browser, see Serverless Architecture.

Additional handler exports #

ExportDescription
render_partial(protocolBytes, stateJson, entry, requestPath, inventoryHex)Returns the JSON partial-navigation response with state included
protocol_tokens(protocolBytes)Returns the protocol CSS token names as a JavaScript array
render_component_templates(protocolBytes, componentTagsJson, inventoryHex)Returns template and style payloads for requested components

Parser-only API #

Use the parser bundle when browser code needs to compile an in-memory file map into protocol bytes.

import init, { build_protocol } from './wasm/parser/webui_wasm_parser.js';

await init();

const files = {
  'index.html': '<h1>{{title}}</h1>',
  'my-card.html': '<p><slot></slot></p>',
  'my-card.css': 'p { color: red; }',
};

const protocolBytes = build_protocol(files, 'index.html');

#

Parse virtual files into a WebUI protocol without rendering.

ParameterTypeDescription
filesRecord<string, string>Map of filenames to content
entrystringEntry HTML filename

Returns protobuf-serialized WebUIProtocol as a Uint8Array. Throws on missing entry files, invalid templates, invalid component authoring, or protocol serialization errors.

Component discovery follows the virtual file map convention: HTML files with a hyphen in the name are registered as components, such as my-card.html for <my-card>. Matching .css files are paired and inlined with CssStrategy::Style.

Combined API #

Use the combined bundle when you want parser and handler exports from one module.

import init, { build_protocol, render } from './wasm/all/webui_wasm_all.js';

await init();

const protocolBytes = build_protocol(files, 'index.html');
let html = '';
render(protocolBytes, stateJson, (chunk) => {
  html += chunk;
}, { entry: 'index.html', requestPath: '/' });

The documentation playground imports this combined bundle and currently uses build_protocol followed by render so it can measure compile and render time separately.

Differences from server-side rendering #

AspectServer (CLI / Rust / Node)WASM (Browser)
Protocol formatProtobuf binaryProtobuf bytes
CSS strategyLink by default, Style or Module when configuredStyle for virtual file builds
File I/OFilesystem and component discovery sourcesVirtual file map
StreamingSupported by native handlersrender() calls a JavaScript chunk callback
Bundle choiceNative crates/addonsHandler-only, parser-only, or combined WASM