A browser engine
for agent swarm

Remaking a browser engine from first principles in Rust, built for small, inspectable workers.

DOM tree
<html>
<head><body>
<nav><main>
<h1><p><a>
Layout boxes
Paint order
  1. background
  2. border
  3. content
  4. evidence
Engine status

One small engine for brave agents.

One page per process. The swarm collects typed results.

Coordinator Task queue URL + action plan
dispatchcollect
Worker / 01browser.jrsession stdin
Worker / 02browser.jrsession stdin
Worker / 03browser.jrsession stdin
snapshottyped effectdocument generation
macOS arm64 release3.2 MiB
Worker boundary1 process
Evidence pathStructured
Current boundaryStatic web

How browser.jr builds a page.

01 / source

How the DOM tree is built

html5ever drives a custom TreeSink. Nodes keep children and weak parent links, then flatten into ordered elements.

src/page/dom.rs ↗
02 / cascade

How styles become computed values

Rules match each element. Specificity and source order resolve conflicts; inline styles run last.

src/page/style.rs ↗
03 / geometry

How layout boxes are computed

Document-order flow resolves containing blocks, margins, borders, padding, widths, and viewport-relative boxes.

src/page.rs ↗
04 / pixels

How paint stays bounded

Supported boxes become clipped fill and border commands. Unsupported paint blocks capture.

src/page/paint.rs ↗
05 / proof

How actions return evidence

Snapshots bind references to a document epoch. Actions return checks, effects, and before/after generations.

src/snapshot.rs ↗

One session. Typed actions. Visible proof.

Line-oriented session / local page
01printf 'open http://localhost:3000\nsnapshot\nget title\nexit\n' \input queued
02  | ./browser.jr --allow-loopback sessionsession started
03open http://localhost:3000document loaded
04snapshotaccessible tree returned
05get titletitle returned
06exitsession closed

Measured as a control path.

Apple M3, one warmup, ten measured samples. Every supported sample passed.

AdapterControl pathMedianp95
browser.jrsession stdin22.55 ms46.39 ms
ChromePlaywright375.36 ms559.17 ms
FirefoxPlaywright643.46 ms813.90 ms
WebKitPlaywright681.95 ms1,348.91 ms
LightpandaPuppeteer / CDP492.45 ms1,461.68 ms
agent-browser / ChromeCLI + daemon7,366.00 ms16,838.12 ms
agent-browser / LightpandaCLI + daemon1,693.90 ms3,392.81 ms
01

Same fixture

One deterministic loopback page.

02

Warm session

One reused session per adapter.

03

Timed work

Setup excluded. Engines run sequentially.

04

Checked result

Expected output required for every sample.

Full workflow: navigate, snapshot, mutate three controls, read state, follow a link, and read its title. Browser-control timings, not engine rankings.

Read the complete result

Deliberately small.

Works today

  • Bounded public HTTP and HTTPS loading
  • Static HTML and a small CSS and layout engine
  • Role, text, CSS, XPath, and attribute locators
  • Typed actions with checks, effects, and generations
  • Agent snapshots and software-rendered screenshots

Current limits

  • No JavaScript runtime
  • No complete DOM, CSS cascade, or layout engine
  • No complete browser paint or compositor
  • No Playwright or agent-browser protocol compatibility
  • No browser window