The token‑efficient
browser for agents.
One persistent browser your agent returns to turn after turn. Drive it from your own agent — skill, MCP, or JS API — or hand whole tasks to its built-in browser agent and read back one answer.
$ betterwright setup
✓ browser ready — downloaded once, kept forever
$ betterwright run -c "await page.goto('https://example.com')"
{"ok": true, "session": "main"}
$ betterwright run -c "return page.title()"
{"ok": true, "result": "Example Domain"}
# session kept alive — logins survive turns, days, restarts
92.7%
Online-Mind2Web — 278/300 tasks
55–85%
fewer observation tokens per turn
5 turns
login → cart → checkout, vs 13
1 turn
for read-only tasks to finish
// tokens are the bottleneck
The observe step is where context windows go to die.
An agent's browser loop is observe → decide → act. Raw HTML dumps, full accessibility trees, and screenshot-only loops burn thousands of tokens per turn — tasks hit context limits and costs climb. BetterWright's whole observation stack is built around that problem:
Compressed agent snapshots — a distilled tree with [ref=eN] markers the model acts on directly
Diff mode — after an action, return only what changed — not the page again
Interactive-only filter — drop static text nodes; keep what the agent can click, fill, or read
Single-call finish — read-only tasks complete in one model turn — no confirmation round-trip
Persistent session — no re-login, no re-navigation, no re-paying to get back where you were
Sub-agent delegation — a whole browsing task costs your main agent one tool call
Observation tokens per turn
12-turn browsing task · illustrative
- Standard accessibility dump
- BetterWright snapshots + diff
55–85% fewer tokens than a standard accessibility dump
// benchmarks
Cheap observations mean fewer turns to the same answer.
Online-Mind2Web
300 real web tasks · 278 solved
Scored by BetterWright's local strict multimodal judge — not an official leaderboard entry.
Scaffold head-to-head
Same model, same effort · 15 tasks × 3 rounds
- BetterWright
- Other agent scaffold
14/15 vs 12/15 correct · 10.2s vs 14.7s median · login → cart → checkout in 5 model turns vs 13.
// what's in the box
Built for agents, priced for context windows.
08 capabilities
Built-in agent loop
Hand a task to betterwright exec — a browser-specialized scaffold with claude/codex/grok adapters and a pluggable model interface.
exec · console · JS API
Sub-agent delegation
One shell command in, one JSON object out — the whole browsing transcript stays inside the sub-agent, not your context window.
one tool call per task
Persistent sessions
One long-lived managed browser — no re-login, no re-navigation, no re-paying the token cost of getting back to where you were.
survives turns · days · restarts
Live view & handoff
Watch and coach the agent in real time. On MFA or a consequential click it pauses — you take the wheel, hit Done, it resumes.
watch · chat · take the wheel
CAPTCHA helpers
Local solving for checkbox, Turnstile, and slider challenges; image grids hand off to the agent's own vision with tile crops.
checkbox · Turnstile · slider
Proof screenshots
Tagged artifacts the agent cites as proof of work — assertions for the real web.
screenshot({ kind: 'proof' })
Human-shaped input
Curved pointer movement, paced typing, eased wheel — no robotic event storms.
zero extra dependencies
Cloaking V2 + Chromium fork
Coherent native fingerprint with per-profile-stable canvas/audio farbling, platform masking, and macOS-metric fonts.
reCAPTCHA v3 → 0.9
Plus: skill packs · interactive console · headed & headless modes
// two ways to use it
Your agent drives — or ours does.
Both modes share the same persistent sessions, snapshots, and live view — start with one and mix in the other later.
Integrated
Claude Code, Codex, Pi, any MCP client, or your own code mans the browser step by step — as one part of a bigger job. No server, no SDK, no glue code.
$ betterwright skill --install # Claude Code skill $ claude mcp add betterwright -- npx betterwright mcp
import { BetterWright } from "betterwright" const bw = new BetterWright() await bw.run("await page.goto('https://example.com')", { session: "dev" })
Standalone agent
Hand over a whole browser task and read back one answer. The browser-tuned agent loop observes, acts, verifies, captures a proof screenshot, and prints one JSON object.
$ betterwright auth --login codex # OAuth, no API key $ betterwright exec "find the top Hacker News story and give me its title and points" --model codex
// why not just playwright?
Playwright is built for tests. An agent is the opposite.
Tests are trusted scripts with known selectors and teardown at the end. An agent is untrusted model output deciding its next step from what it sees — in a browser that must still be there next turn.
Capability map
- BetterWright
- Playwright
qualitative · 0–5 per axis
Observations
- Playwright
- Raw accessibility tree or DIY HTML
- BetterWright
- Compressed, diffable snapshots
Session
- Playwright
- Browser per script
- BetterWright
- One persistent managed browser
Agent loop
- Playwright
- DIY scaffolding
- BetterWright
- Built-in browser-tuned agent loop
CAPTCHAs
- Playwright
- Out of scope
- BetterWright
- Local solve + vision handoff
Human in the loop
- Playwright
- Out of scope
- BetterWright
- Watch, chat, or take over on handoff
Evidence
- Playwright
- Assertions
- BetterWright
- Tagged proof screenshots
| Capability | Playwright | BetterWright |
|---|---|---|
| Observations | Raw accessibility tree or DIY HTML | Compressed, diffable snapshots |
| Session | Browser per script | One persistent managed browser |
| Agent loop | DIY scaffolding | Built-in browser-tuned agent loop |
| CAPTCHAs | Out of scope | Local solve + vision handoff |
| Human in the loop | Out of scope | Watch, chat, or take over on handoff |
| Evidence | Assertions | Tagged proof screenshots |
One browser. Every agent.
Setup downloads the browser once — never as an npm lifecycle side effect, so installs stay predictable with --ignore-scripts. Open source, MIT licensed.
$ npm install -g betterwrightrequires Node.js 22+
$ betterwright setupdownloads the browser once (~200 MB)
$ betterwright doctorconfirm everything resolves
then: betterwright exec "your task here" --model codex