{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/header.png\" alt=\"Dev Browser - browser automation for coding agents\" width=\"100%\">\n</p>\n\nBrought to you by [Do Browser](https://dobrowser.io).\n\n`dev-browser` lets coding agents control Chrome with short JavaScript scripts. The browser stays open between calls,\nso an agent can navigate once, inspect the page, act, and verify the result without starting over each time.\n\n**Key features:**\n\n- **Persistent pages.** Named tabs carry state across scripts.\n- **Compact snapshots.** Accessibility trees give agents readable output and stable element refs.\n- **Real Puppeteer.** Scripts use the Puppeteer Page API plus a small set of agent-focused helpers.\n- **Launch or attach.** Start an isolated Chrome profile or connect to a browser you already have open.\n\n## Demo\n\nhttps://github.com/user-attachments/assets/c6cf7fb9-b1dc-46ed-93b9-6e7240990c53\n\n## CLI installation\n\n```bash\nnpm install -g dev-browser\ndev-browser install    # only needed if dev-browser cannot find Chrome\n```\n\nThe release binary includes Bun and Puppeteer. Node is not required after installation. macOS and glibc Linux are\nsupported; Windows and musl Linux are not yet supported.\n\nSnap-packaged Chromium cannot read the default `~/.dev-browser/v1` directory. On Ubuntu, use `dev-browser install`\nor point `DEV_BROWSER_CHROME` at another Chrome binary.\n\nIf your package manager blocks lifecycle scripts, run `npm rebuild -g dev-browser`, `pnpm approve-builds -g\ndev-browser`, or `bun pm -g trust dev-browser`. The CLI will also try to download its binary on first use. For a\nprivate mirror, set `DEV_BROWSER_DOWNLOAD_BASE`; set `DEV_BROWSER_SKIP_DOWNLOAD=1` if you install the binary yourself.\n\n### Quick start\n\n```bash\n# Launch a headless browser and run a script\ndev-browser --headless <<'EOF'\nconst page = await browser.getPage(\"main\");\nawait page.goto(\"https://example.com\");\nconsole.log(await page.title());\nEOF\n\n# Attach to Chrome started with `dev-browser chrome`\ndev-browser chrome\ndev-browser --connect <<'EOF'\nconsole.log(await browser.listPages());\nEOF\n```\n\nChrome 136 and newer ignore remote-debugging flags on the default profile. `dev-browser chrome` handles this by using\na dedicated profile and checking that Chrome actually started.\n\n### Using it with coding agents\n\nTell the agent to run `dev-browser --help`. The built-in guide covers the current API and the preferred\nlook → act → verify workflow.\n\nAgents that discover local skills can install the bundled skill explicitly:\n\n```bash\ndev-browser install-skill --codex   # ~/.codex/skills/dev-browser/SKILL.md\ndev-browser install-skill --claude  # ~/.claude/skills/dev-browser/SKILL.md\ndev-browser install-skill --agents  # ~/.agents/skills/dev-browser/SKILL.md\n```\n\nRun `dev-browser install-skill` without flags to update all three locations.\n\n### Idle browser cleanup\n\nLaunched browsers close after 30 minutes without a script by default. Change that per command, in the environment, or\nin `~/.dev-browser/v1/config.json`:\n\n```bash\ndev-browser --idle-timeout 5m < script.js\nDEV_BROWSER_IDLE_TIMEOUT=1h dev-browser -e 'await browser.listPages()'\n```\n\n```json\n{\n  \"idleTimeout\": \"5m\"\n}\n```\n\nDurations accept `30s`, `5m`, `1h`, or raw milliseconds. Set the value to `0` to keep a launched browser open until\n`dev-browser stop`. Attached browsers are never closed by idle cleanup. Profiles, cookies, and login state remain on\ndisk when a launched browser closes.\n\n<details>\n<summary>Allowing dev-browser in Claude Code without permission prompts</summary>\n\nAdd `dev-browser` to the `allow` list in `.claude/settings.json` for one project or `~/.claude/settings.json` for every\nproject:\n\n```json\n{\n  \"permissions\": {\n    \"allow\": [\"Bash(dev-browser *)\"]\n  }\n}\n```\n\nThis allows any matching command without another prompt. Only do this where you trust the scripts being run:\n`node:vm` gives each script fresh globals, but it is not a security sandbox.\n\n</details>\n\n<details>\n<summary>Legacy Claude Code plugin installation</summary>\n\n```text\n/plugin marketplace add sawyerhood/dev-browser\n/plugin install dev-browser@sawyerhood/dev-browser\n```\n\nRestart Claude Code after installation.\n\n</details>\n\n## Script API\n\nScripts get these globals:\n\n```javascript\n// Browser control\nbrowser.getPage(nameOrId)    // Get/create a named page, or attach by target ID\nbrowser.newPage()            // Create an anonymous page; close it yourself\nbrowser.listPages()          // [{ id, url, title, name }]\nbrowser.closePage(name)      // Close a named page\n\n// File I/O, restricted to ~/.dev-browser/v1/tmp\nsaveFile(name, data)\nreadFile(name)\n\n// Output\nconsole.log()\nconsole.warn()\nconsole.error()\n```\n\nTop-level `await` works, and the last expression becomes the command result. Pages are real [Puppeteer Page\nobjects](https://pptr.dev/api/puppeteer.page) with a few additions:\n\n```javascript\nawait page.snapshot({ interactive: true }) // Accessibility tree with refs such as e12\nawait page.click(\"ref/e12\")                 // Refs work in Puppeteer selector methods\nawait page.ref(\"e12\")                       // ElementHandle for a ref\nawait page.shot()                           // JPEG path and CSS-pixel dimensions\nawait page.waitForLoad()                    // Wait for navigation, requests, and DOM activity to settle\nawait page.fill(\"#email\", \"me@example.com\")\n```\n\nEach command runs in a fresh `node:vm` context inside the daemon. This keeps script globals separate, but it is not a\nsecurity boundary. When a command finishes or times out, its page, locator, browser-context, and registry operations\nare closed so detached work cannot interfere with the next command.\n\nScripts may run concurrently. Browser and page creation are serialized, as are input operations on different tabs\nthrough a bring-to-front lock. Two scripts using the same named page can still interleave.\n\nSee [`dev-browser --help`](docs/help.md) for the full API, error behavior, configuration, JSON output, MCP tools, and\nexamples.\n\n## Connecting to an existing browser\n\n`--connect` accepts auto-discovery, a port, an HTTP URL, a WebSocket URL, or a raw CDP Unix socket:\n\n```bash\ndev-browser chrome --profile work\ndev-browser --connect -e 'await browser.listPages()'\ndev-browser --connect 9222 -e 'await browser.listPages()'\ndev-browser --connect 'wss://provider.example?token=…' -e 'await browser.listPages()'\n```\n\nAttached browsers belong to the user. dev-browser extends only the tabs a script asks for and never closes the browser\nbecause of an idle timeout. Credentials are redacted from logs and status output, while differently authenticated\nendpoints remain separate sessions.\n\n## MCP\n\n```bash\nclaude mcp add dev-browser -- dev-browser mcp --headless\n```\n\nThe server exposes `dev_browser_run`, `dev_browser_pages`, `dev_browser_browsers`, `dev_browser_stop`, and\n`dev_browser_help` over the same warm daemon as the CLI.\n\n## Upgrading to 1.0\n\nVersion 1.0 replaces the Playwright/QuickJS implementation from dev-browser 0.2 with the Puppeteer/Bun implementation\ndeveloped as doobie. Its state lives under `~/.dev-browser/v1`, separate from both older installations.\n\nTo copy durable doobie state:\n\n```bash\ndoobie stop\ndev-browser migrate-from-doobie\n```\n\n`migrate-from-doobie` leaves `~/.doobie` untouched. Scripts written for dev-browser 0.2 need to replace helpers such as\n`snapshotForAI()` and `getByRef()` with `snapshot()` and `ref/eN`. Computer-use helpers under `page.cua` and\n`page.domCua` are not part of 1.0.\n\n## Benchmarks\n\nMeasured on Linux with a headless browser and warm daemon, medians of 9 runs:\n\n| Scenario | Time |\n| --- | ---: |\n| Empty script | ~13 ms |\n| `getPage(\"x\")` + `page.title()` | ~14 ms |\n| `page.snapshot()` on a SERP-like page | ~18 ms |\n| `page.shot()` | ~36 ms |\n| Cold daemon and Chrome launch | ~280 ms |\n\nRun them with `bun run build && bun run bench/run.ts --runs 9`. The older end-to-end comparison is in\n[dev-browser-eval](https://github.com/SawyerHood/dev-browser-eval).\n\n## Development\n\n```bash\nbun install\nbun run dev -- -e '1+1'\nbun test\nbun run build\n```\n\nDesign notes live in [docs/design-decisions.md](docs/design-decisions.md).\n\n## Releasing\n\nSee [RELEASING.md](RELEASING.md) for release-candidate testing, npm trusted publishing, and post-release verification.\n\n## License\n\nMIT\n\n## Author\n\n[Sawyer Hood](https://github.com/sawyerhood)\n",
  "bytes": 8327,
  "sha": "e37d86341259c8cef765e36bce93698873ff9311d9fb1484aa2d57d2bd2d3559",
  "repo_slug": "sawyerhood/dev-browser",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/skl_sawyerhood_dev_browser_dev_browser_4a02fe31/readme"
}