Back to Devoured - August 20, 2026
DEVOURED
BetterWright (GitHub Repo)

BetterWright (GitHub Repo)

Tech GitHub
BetterWright is a persistent, policy-guarded browser designed specifically to minimize token usage for AI agents browsing the web.
What: BetterWright provides an automated Playwright environment that manages sessions, credentials, and network policies while optimizing web content into token-efficient snapshots. It supports multiple integration methods, including MCP servers and standalone agents, to reduce the context window burden compared to raw HTML or accessibility dumps.
Why it matters: By addressing the high token costs associated with agents parsing full-page DOMs, this tool makes long-running browser tasks more economically viable for LLM-based systems.
Takeaway: If your AI agent is hitting token limits during web tasks, try `npm install -g betterwright` and switch from raw HTML dumps to its compressed agent snapshots.
Deep dive
  • BetterWright treats the browser as a persistent stateful entity rather than a transient teardown-based test environment.
  • It uses compressed snapshots (pruning non-actionable elements) to keep context windows small.
  • The tool includes an AES-256-GCM vault for handling credentials without exposing secrets to model code.
  • Built-in 'Live View' functionality allows human intervention during MFA or CAPTCHA challenges.
  • It offers 'diff mode' to only send changes after an agent action, further reducing token consumption.
  • The browser uses 'BetterChromium' with profile-stable fingerprinting, improving the success rate of automated workflows.
Decoder
  • CDP: Chrome DevTools Protocol; allows tools to instrument, inspect, debug, and profile Chromium-based browsers.
  • MCP: Model Context Protocol; an open standard that allows AI models to connect to data sources and tools consistently.
  • Context Window: The limit of information (tokens) an AI model can process at once.
Original article

BetterWright

The token-efficient browser for AI agents.

One persistent, policy-guarded 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 just read the answer.

npm install -g betterwright && betterwright init

betterwright run -c "await page.goto('https://example.com'); return page.title()"
# {"ok": true, "result": "Example Domain", ...}

init downloads the browser, wires up whichever agents it finds on your machine, and proves it works by loading a real page. One command, no choices to make up front.

Compressed snapshots instead of raw HTML or a full accessibility dump · read-only tasks finish in one model turn · persistent sessions so you don't re-pay login and navigation cost every step.


Two ways to use it

You want… You get…
Integrated your agent (Claude Code, Codex, Pi, any MCP client, your own code) to browse as one part of a bigger job a skill, MCP server, or JS API through which your agent mans the browser step by step
Standalone agent to hand over a whole browser task and read back one answer betterwright exec "<task>" — BetterWright's own browser-tuned agent loop does the driving; you (or your agent) get one JSON result

They share everything — the same persistent sessions, vault, network policy, and snapshots — so you can start with one and mix in the other later.

1. Integrated — your agent drives the browser

Any agent that can run a shell command can drive the browser. betterwright skill prints the instructions that teach it how — CLI usage plus operator guidance. No server, no SDK, no glue code.

# The short version: init detects your agent hosts and wires them all.
betterwright init

# Or do it by hand, one host at a time:
betterwright skill --install       # ~/.claude/skills + ~/.agents/skills (browser + e2e-review)
betterwright skill --install --all # also ~/.cursor/skills
betterwright skill --status        # where it landed, and whether it is current
betterwright skill >> ~/.codex/AGENTS.md   # Codex reads an instructions file

# Any custom agent — the same instructions ship as SKILL.md in this repo
# and the npm package (node_modules/betterwright/SKILL.md); copy it wherever
# your agent reads skills, or print it with `betterwright skill`.

# MCP (stdio server: browser, browser_login, browser_download, browser_handoff, browser_doctor)
npm install -g betterwright @modelcontextprotocol/sdk
claude mcp add betterwright -- npx betterwright mcp
betterwright mcp --check           # why does my client show no tools?

# Pi Coding Agent (native persistent tools, trusted login, approval-gated downloads)
pi install npm:betterwright

After an npm upgrade, setup / update refresh already-installed skill files, and doctor says so if one is still stale.

Or drive it from your own code:

import { BetterWright } from "betterwright";

const bw = new BetterWright();
await bw.run("await page.goto('http://localhost:5173')", { session: "dev" });
const title = await bw.run("return page.title()", { session: "dev" });
console.log(title.result);
await bw.close();

run() takes a string of async Playwright JavaScript with sandboxed globals — page, snapshot, screenshot, human, credentials, and friends — and returns one result envelope.

2. Standalone — BetterWright is the browser agent

BetterWright ships its own browser-tuned agent loop. Plug in a model, hand it a task in plain language:

betterwright auth --login codex     # OAuth sign-in, no API key to paste
betterwright exec "find the top Hacker News story and give me its title and points" --model gpt-5.6-sol

The loop observes with compressed snapshots, acts, verifies, captures a proof screenshot, and prints one JSON object — answer, steps, token usage, proof path.

Models are selected by real id, not by adapter nickname. Pass the model id you want (gpt-5.6-sol, claude-opus-4-8, qwen3:8b, …).

You have… Typical start
ChatGPT / Codex subscription betterwright auth --login codex → --model gpt-5.6-sol
Anthropic API key ANTHROPIC_API_KEY=… → --model claude-opus-4-8
xAI (OAuth or API key) betterwright auth --login grok or XAI_API_KEY → --model grok-4.3
Local Ollama pull a tool-calling model → --model qwen3:8b or ollama/…
Local vLLM serve with tool-calling enabled → --model <id> or vllm/<id>
OpenRouter OPENROUTER_API_KEY=… → --model <author/model>
Any OpenAI-compatible /v1 --base-url https://host/v1 --model <id>

Run bare betterwright for the interactive console: one browser session across tasks, steps streaming as they happen, /model, /endpoint, and /models, plus an ask tool so the agent can check with you before consequential choices.

Use it as a sub-agent. Because exec is one shell command in and one JSON object out, a coding agent can delegate entire browser tasks to it:

betterwright exec "log in to staging and download this month's invoice" --model gpt-5.6-sol

Tokens are the bottleneck

An agent's browser loop is observe → decide → act, and the observe step is where context windows go to die. BetterWright's whole observation stack is built around that problem:

Mechanism Token effect
Compressed agent snapshots Playwright's mode: "ai" accessibility tree with everything an agent cannot act on pruned out.
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
Persistent session One long-lived browser: no re-login, no re-navigation.

Watch it, coach it, take the wheel

Every run can carry a self-hosted live view: a web page showing the browser in real time, with chat to guide the agent between turns and a handoff flow for the moments automation shouldn't finish alone — MFA, a resistant CAPTCHA, a consequential click.

betterwright exec "…" --live-view          # watch the whole run
betterwright view --expose tailscale       # drive a headless VPS browser from your laptop
betterwright view --set-password           # lock every viewer behind a password

Why not just Playwright?

Playwright is built for tests: trusted scripts, known selectors, teardown at the end. An agent is the opposite — untrusted model output deciding its next step from what it sees, in a browser that must still be there next turn.

Install

Requires Node.js 22+. Setup downloads the pinned native BetterChromium browser for this host; GPU-less Linux runs it with the SwiftShader software renderer.

npm install -g betterwright
betterwright init      # guided: browser + agent wiring + a real page load

Getting a password back out

The vault fills logins without ever handing a secret to model code — which would leave you locked out of a password your agent generated during a signup. So there is a separate, human-only door:

betterwright vault list                # metadata: site, username, when
betterwright vault copy <id>           # password → clipboard, never the screen
betterwright vault show <id> --reveal  # print it (refuses to a pipe or a file)

Sessions and profiles

All state lives under $BETTERWRIGHT_HOME (default ~/.betterwright): the persistent browser profile, the credential vault, and artifacts.

  • --session <name> — parallel lanes in one browser, sharing one cookie jar.
  • --profile <name> — a separate identity: its own cookie jar, session daemon, and history.

Scope and responsible use

BetterWright automates a browser under your direction, including signing in and interacting with simple CAPTCHAs on sites you are authorized to use. It is not built for bulk account creation, credential stuffing, or scraping behind anti-bot walls at scale.

License

MIT.

Explore all 57 articles in today's digest

Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi