Rune - deterministic browser engine

Render real web apps.
Let agents drive them.

Rune is a deterministic browser engine that renders real pages and React apps on the GPU, then exposes the whole running app as an inspectable representation agents can read and control. No Chromium.

Runereal page - clean render

source

<section class="hero">

<h1>Ship faster</h1>

<p>One platform.</p>

<button>Get started</button>

</section>

rendered on wgpu

Ship faster

Get started
one GPU pass - no Chromium
Source code for a web interface on a screen
Rune renders real web code. Photo is illustrative.

What Rune does

A real browser engine, built to be read and driven.

Rune renders the real web, but it is not a black box you can only screenshot. These are its strengths - one short line each, the detail is further down.

Real web

Runs real HTML, CSS, JS and React

Loads real HTTP/HTTPS pages and unmodified React apps - no bespoke framework or lookalike toolkit.

Rendering

One GPU pass

Parsed, cascaded and laid out into a paint IR, then drawn in a single depth-sorted pass on wgpu. No Chromium, no Electron.

Determinism

Deterministic by design

The host owns timers and scheduling, so the same IR and input replay to the same frames - a bug is a fixture, not a flake.

Inspectable

The app is data you can read

Every app is a content-addressed IR package you can open and inspect - no opaque bundle, no screenshot scraping.

Agents

Agent-controllable

A typed, named action surface over the IR that agents call directly - not pixels and coordinates.

Fidelity

Checked against Chrome

A Playwright harness diffs computed style and layout against Chrome as oracle and gates on the delta.

One renderer

One renderer, deterministic by design.

Rune has a single Rust rendering backend on wgpu. Real pages and React apps are parsed, cascaded and laid out, then painted in one depth-sorted GPU pass. And because the host owns the scheduler - timers, task queues, animation frames - the same input replays to the same frames, so a run is reproducible rather than racing the wall clock.
  • Real HTML, CSS, JS and React, rendered without Chromium
  • One wgpu GPU pass: gradients, shadows, z-layering, subpixel text
  • Host-owned scheduling, so runs replay exactly
Web page markup and styles on a code editor screenRenderer
Web code on a screen. Illustrative photo.

Built for agents

Built for agents to drive.

Most tools make an agent screenshot pixels or scrape an opaque DOM, then guess at coordinates. Rune exposes the whole running app as an inspectable representation and a typed, named action surface. An agent reads real state and calls a semantic tool - it does not reverse-engineer a picture. The MCP surface is further down, under the hood.
  • Read DOM and computed style straight from the IR
  • Call named actions over detir-mcp, not pixel clicks
  • Watch changes stream back as IR diffs to confirm
Lines of source code lit in cool blue on a screenAgents
Source code on a screen. Illustrative photo.

Where it fits

A different tool from a headless browser.

Rune is a deterministic, inspectable, agent-driven browser engine. The neighbours keep their real strengths - it trades full web compatibility for state you can read, runs you can replay, and actions agents can call by name.

RuneHeadless Chrome + PuppeteerElectron + CEFServo
Reads app state asInspectable IR - DOM plus computed styleScreenshot or scraped DOMScraped DOM via remote debuggingInternal DOM / layout tree
DeterminismHost owns timers, queues and seeded PRNGNondeterministic - races the wall clockNondeterministic - races the wall clockNondeterministic
RenderingOne wgpu GPU pass, no ChromiumBlink + Skia - mature, full-fidelityBlink + Skia - matureWebRender on the GPU
Agent actionsSemantic MCP tools over the IRPixel clicks and selectorsIPC to the embedded pageNone - an engine, not an agent surface
Web compatibilityPartial - v0.1.0, not full-compat yetBroad and battle-testedBroad and battle-testedGrowing, independent engine

Puppeteer and Electron are mature and battle-tested, and Servo is a capable independent engine. Rune is pre-1.0 and does not match them on full web compatibility - we say that plainly. What it adds is an inspectable IR, host-owned determinism and a typed MCP action surface built for agents.

Under the hood

How it actually holds together.

The story above is the plain version. For evaluators, here is the engine underneath - one Rust rendering backend on wgpu, an inspectable IR, host-owned scheduling and a typed agent surface.

From source to one GPU pass

Web content is parsed, cascaded and laid out into a paint IR, then drawn in a single depth-sorted pass. Web-standards mode runs scripts on detir-js (V8 by default; QuickJS or Boa for light targets); direct-IR mode lets Rust host or agent code mutate the scene graph. Both produce the same IR.

01

HTML / CSS / JS

Real page or React app

02

DOM

Parsed document tree

03

Computed style

Cascade, 160+ properties

04

Layout boxes

Block, flex, grid, inline

05

Paint IR

Flat, ordered display list

06

One GPU pass

Depth-sorted on wgpu

The app is data you can read

A Rune app is a content-addressed IR package: a DETIR.MANIFEST.json header, a per-asset DETIR.TOC.json, and .vizr view nodes carrying computed_style and interactivity. Anything that can read the IR can inspect and drive the app.

welcome.vizrview node

{

"id": "video_play_button",

"node_id": "VIDCTLPL",

"type": "button",

"data-onclick": "video_play:VIDFRST1",// bound action

"computed_style": {

"background_color": "#10b981",

"color": "#ffffff",

"font": { "size": 12.0 }

}

}

A .vizr view node: a JSON tree with computed_style and interactivity. The highlighted data-onclick binds a named action to the node - an agent reads this, it does not guess.

Deterministic by design

In a normal browser the JS engine decides when things run, so execution races the wall clock. In Rune the host owns the scheduler - the same IR and input replay to the same frames, so a bug is a fixture, not a flake.

the host ownstimerstask queuesmicrotask checkpointsrequestAnimationFrameobserversseeded Math.random

Agent control via detir-mcp

detir-mcp is a JSON-RPC 2.0 dispatcher over the WAID action registry. Agents call a named {app_id}:{action} tool, then read the mutation streamed back - no screenshot, no coordinates.

detir-mcpJSON-RPC 2.0

{ "method": "tools/call",

"name": "showcase:video_play",

"arguments": { "target": "VIDFRST1" }

}

/api/ir-diffmutation stream

{ "op": "replace_text",

"target": "VIDCTLPL", "text": "Pause"

}

Fidelity, measured against Chrome

Style fidelity is a test, not a claim. A Playwright harness diffs getComputedStyle and getBoundingClientRect against Chrome as oracle and gates on the delta.

651 -> 0

style-cascade deviations

driven to zero on the initial 3-page corpus

160+

CSS properties rendered

cascade, layout, paint - measured, not asserted

11 / 11

Chrome-oracle gates

passing at 1280x800 and narrow widths

49

crates

one Rust workspace, v0.1.0

Honest today: 183 deviations still remain across 480 nodes (159 are layout width / height). Zero on real pages is the target, not the current state.

Request access

The deterministic browser engine agents can actually control.

Rune is private and access-gated while it is early - v0.1.0, under active development. Access is granted on request. Tell us what you are building and we will get you in and compare notes.

Access granted on request - no public repository