Manuk — written from scratch in Rust — compiled to WebAssembly and executing on this page. It is parsing, cascading, laying out and rasterizing real websites in your browser right now. Switch to Agent view to see the accessibility tree an LLM drives it through; switch to Boxes to see the raw geometry. Point at anything and it reports its own engine state — straight out of Stylo, Taffy and the a11y tree, never re-derived for display.
Real: Stylo (Firefox's cascade), Taffy (flex/grid), tiny-skia (the
rasterizer), usvg-backed SVG, @container/@supports queries, manuk-a11y (the
semantic tree an agent reads), and this engine's own DOM, inline/float/table layout, paint, hit-testing
and stacking. Scrolling re-renders. Every panel reads the actual engine state.
Not real here: no JavaScript, and no live fetching — these are bundled snapshots
of real sites, stylesheets inlined. Saying so is the only thing that makes the rest believable.
The pages below are curated to the near-Chromium end — compare them yourself with the button. The figures above are the strict bar across an uncurated sample, so they read lower on purpose; we drive them in the open. M2 — does the site function (its JS runs, forms submit, links navigate) — is certified after M1, and today's honest proxy is the share that boot and render at all. live burndown ↗
The native engine embeds SpiderMonkey — real JS, real JIT. But this demo targets
wasm32-unknown-unknown, and SpiderMonkey is C++: mozjs links a native
library with no build for that target. SpiderMonkey can run on wasm, but only as an
interpreter — WebAssembly forbids the runtime code generation a JIT is — and it ships
as a separate WASI module, unlinkable into this binary. So the demo is the rendering engine and the
agent's observation channel, in full; the script runtime is native-only.
The Agent view needs none of that: an accessibility tree (role + name + state + a click box) is
a pure function of the parsed DOM and the laid-out geometry. It is exactly what the headless
agent front-end feeds a model instead of a screenshot — computed here, with no JS, from
the same two things the render is.