The browserfor your agent.
bun install -g betterwrightThe loop
Snapshots
One snippet in.One snapshot back.
A snippet runs Playwright code in a sandboxed worker and returns a result envelope. Request a snapshot when you need a compressed accessibility tree, sized for a context window.
import { withBrowser } from "betterwright/sdk" const proof = await withBrowser(async (bw) => { await bw.run("await page.goto('https://shop.example/cart')") // what the model reads: the tree on the right const tree = await bw.run("return snapshot({ interactive: true })") // act on a ref with a human-shaped click await bw.run("await human.click(page.locator('aria-ref=e7'))") // only what changed, not the page again await bw.run("return snapshot({ interactive: true, diff: true })") return bw.run("return screenshot({ kind: 'proof', name: 'checkout' })") })
What the agent sees
Interactive snapshots drop unrelated prose while retaining controls, live status, and short item or table context. Actionable refs let the model target controls without re-deriving a selector.
Only what changed
With matching snapshot options, diff mode returns changed lines or reports no changes.
Honest failures
Typing reads the field back and fails the step when the text is not there. An editor that swallowed keystrokes is a miss, not a success.
Evidence the agent cites
A proof screenshot is an artifact, not a wall of pixels in the context. The result points at it.
Architecture
Your agent decides.BetterWright drives.The browser stays open.
Three layers, one clean seam between each. The agent never touches the session; the session never touches the task. Swap the bottom layer with one configure command.
- 01
Decides
Your agent
Owns the task. Reads a snapshot, picks the next step.
- 02
Drives
BetterWright
Owns the session. Network policy, credential vault, snapshots, live view.
- 03
Stays open
The browser
Managed BetterChromium by default: downloaded once, coherent identity, GPU when the host has one.
Cloud browsers
Browser providersFull lifecycle start · list · stop
- Kernel
- Browserbase
- Steel
- Anchor
- Hyperbrowser
- Browser Use
Connect bring your own endpoint
- Browserless
- Bright Data
- Oxylabs
Mechanisms & evidence
Read what matters.Check what changed.
Prune
Focused observations
Interactive snapshots retain controls, live status, and short item or table context.
Diff
Compare the same view
Diff mode returns changed lines against a previous snapshot with the same options.
Reuse
Persistent sessions
Return to the same browser session instead of repeating login and navigation each turn.
The head-to-head reports are development case studies, not valid comparative benchmarks: the reference implementations are unnamed and unversioned. They do not establish a general speed or token advantage. Method and raw runs are in the repo.
Entry points
Two ways to drive it.One session underneath.
The same persistent sessions, vault, network policy, and snapshots sit under every entry point, so you can start with one and mix in the others later.
Your agent, step by step
Claude Code, Codex, Cursor, Pi, or any MCP client mans the browser as one part of a bigger job. No server, no glue code.
import { withBrowser } from "betterwright/sdk" const title = await withBrowser(async (bw) => { await bw.run("await page.goto('https://example.com')") const r = await bw.run<string>("return page.title()") return r.ok ? r.result : null })
Your own code, one import
withBrowser builds the client, runs your function, and closes it on the way out and on a thrown error. Results are values; check ok and decide.
$ betterwright exec "find the top HN story and give me its title" --model gpt-5.6-sol { "ok": true, "steps": 4, "toolCalls": 5, "answer": "…", "usage": { "inputTokens": 6880, "outputTokens": 1330 }, "proof": "…/proof-hn.png" } # the 30 snapshots in between never reach your main agent
Hand over the whole task
One shell command in, one JSON object out. The browsing transcript stays inside the sub-agent, so a 30-turn checkout costs your main agent one tool call.
Take the wheel when it matters
Watch the run in a browser tab, chat between turns, and take over for MFA or a consequential click. Hit Done and the agent resumes.
Install it. Point your agent at it. Read the answer.
