One Livecode wasm engine can run several stack windows — each window its own canvas, the engine as window manager. This page records what the engine's own code proves, what that means for wiki widgets, and the three honest ways to share an engine between them. Read from the 10.0.2-rc-4 glue on 18 July 2026.
# What the engine proves The emscripten glue carries a full window manager:
MCEmscriptenCreateWindow MCEmscriptenDestroyWindow MCEmscriptenSetWindowRect MCEmscriptenGetWindowRect MCEmscriptenRaiseWindow MCEmscriptenSetWindowVisible MCEmscriptenGetStackForWindow MCEmscriptenBlitToWindowCanvas
It also creates canvas elements dynamically — a canvas per stack window, each absolutely positioned as its window rect, which is exactly the behaviour Full Screen Wasm measured from outside. And both bridge directions exist: JavaScript calls into stacks through `document.liveCode.findStackWithName`, and Livecode script calls out through `EvaluateJavaScriptWithArguments` — the `do ... as "JavaScript"` path. The desktop intuition carries over: one engine, many windows, one message path.
# The memory truth Across a lineup of widgets the network pays for the engine once — Many Wasm Widgets holds the measurements. Memory is different: each widget iframe instantiates its own engine, with its own linear memory. The browser shares the compiled code between instances of the same engine url, so the multiplied cost is the runtime heap and the stack data, per running widget. Pages that want a light footprint mark items `BOOT click`.
# Layer one — many windows in one widget Works today, with nothing to build. A widget whose stack opens substacks — `open stack "Gauge"` — gets a canvas per window inside its own iframe, engine managed, movable and raisable. Between those stacks the messaging is native Livecode: send, dispatch, shared globals, one message path. The widget becomes a small HyperCard screen embedded in the page. All it needs is a stack authored with substacks; the shell's fullscreen fit modes assume a single canvas today and would be loosened once such a stack exists to test against.
# Layer two — one engine behind many widgets The ambitious version. Browsing contexts own their DOM, so one engine cannot paint into scattered iframes. The workable design is a portal: a hidden engine host runs every stack; each widget shows its stack's canvas through `captureStream` into a video element, and forwards pointer and keyboard events back as synthesised DOM events. Real engineering — input fidelity, focus, fullscreen — and only worth it if per widget heap cost starts to hurt. Parked, on purpose.
# Layer three — the wiki message bus Messaging between separate widget engines, buildable now on verified machinery. A stack sends:
on mouseUp do "wikiSend('Panel','gaugeChanged',42)" as "JavaScript" end mouseUp
The shell defines `wikiSend` and posts to the parent page; the plugin routes by the target widget's NAME — across items, and across pages in the lineup — and the receiving shell delivers:
document.liveCode.findStackWithName('Panel').gaugeChanged(42)
Cross engine dispatch with serialisable arguments, fire and forget. It is also, not coincidentally, the transport the WikiScript stage dialect will speak: the same bus that lets stacks talk to each other lets the literate language command them.
# What stack authors provide The receiving half lives in the stack: declare the handlers — `gaugeChanged`, `pinged`, `fullscreenChanged` — in the standalone's JavaScript Handlers setting, and handle them in Livecode script. Export against the shared engine version and drop the `standalone.zip` into `assets/wasm/shared/` under its own name; the engine cache does the rest. A Ping and Pong pair, one of them carrying a substack, would prove layer one and layer three in a single afternoon.
# See - Livecode Wasm and Full Screen Wasm - Many Wasm Widgets and Wasm Widget Demo - Webpageinteractionstack and WikiScript