---
name: dev-browser
description: >
  Drives a real Chromium browser from Claude Code and from Bash CLI — navigate
  pages, click elements, read DOM, take screenshots, run end-to-end checks.
  The SmartStack Studio uses this skill as the test engine for Phase 5 UI
  tests. Activate when the user asks to open a URL, click a button, test a
  web page, verify a rendered layout, reproduce a UI bug, submit a form, or
  script any browser interaction. Keywords: browser, navigate, click, screenshot,
  DOM, Chromium, Chrome, webpage, URL, visual test, UI verification, E2E.
group: B
allowed-tools: [Read, Glob, Grep]
---

# dev-browser

Wraps the upstream **dev-browser** CLI + plugin by Sawyer Hood. Scripts run
in a QuickJS WASM sandbox with access to a Playwright-controlled Chromium —
no direct host filesystem or network access, apart from `~/.dev-browser/tmp/`
and the browser context itself.

- **Upstream repo**: https://github.com/SawyerHood/dev-browser (MIT licensed, actively maintained — see `CONTRIBUTING.md` if an issue blocks the Studio integration).
- **Pinned version used by SmartStack Studio**: `0.2.7` (released 2026-04-09).

## When to use this skill

Activate when the user wants Claude to interact with a web page:

- "Open the login page and check that the form renders correctly"
- "Navigate to our staging site and verify the new button appears"
- "Reproduce the bug on the pricing page"
- "Take a screenshot of the dashboard after I click Save"
- "Test that the feature works end-to-end in the browser"
- "Scrape the table from this reference docs page"

### When NOT to use

- Static HTML parsing with no JS / no interaction needed — prefer a direct fetch
- Testing Node/backend code — use regular test runners (xUnit, Vitest)
- Reading local filesystem content — use Read / Glob / Grep

## Installation

Two usage modes. SmartStack Studio uses **mode A** (CLI) in Phase 5 and
leaves **mode B** (Claude Code plugin) available for exploratory chat-driven
debugging.

### Mode A — CLI (used by Phase 5 ui-test)

```bash
npm install --save-dev dev-browser@0.2.7
npx dev-browser install   # downloads a bundled Chromium via Playwright
```

The SmartStack scaffolders add `"dev-browser": "0.2.7"` to the generated
project's `package.json` devDependencies. The `scaffold-ui-test` CLI expects
`npx dev-browser --help` to succeed before any test runs.

### Mode B — Claude Code plugin (optional, for exploratory debugging)

```
/plugin marketplace add sawyerhood/dev-browser
/plugin install dev-browser@sawyerhood/dev-browser
```

The plugin registers nested commands that Claude can call directly from a
conversation. When the user asks Claude (via the Studio chat) to "open
this page and tell me what you see", Claude uses these nested commands.

## Invocation (Mode A — CLI)

Scripts are passed via **stdin** (no `--script` or `--file` flag exists in
v0.2.7). A minimal headless invocation:

```bash
dev-browser --headless <<'EOF'
const page = await browser.getPage("main");
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
console.log(JSON.stringify({ title: await page.title() }));
EOF
```

Script contract:

- Plain JavaScript, not wrapped in a function. Top-level `await` is supported.
- The `browser` global exposes `getPage(name)`, `newPage()`, `listPages()`, `closePage(name)`.
- A page object exposes the Playwright Page API: `goto`, `click`, `fill`, `locator`, `evaluate`, `screenshot`, `on(event, cb)`, `waitForURL`, etc.
- File I/O is restricted to `~/.dev-browser/tmp/` via `saveScreenshot(buf, name)`, `writeFile(name, data)`, `readFile(name)`.
- The script must emit **one** final `console.log(JSON.stringify(result))` on stdout. Intermediate trace output should go to `console.warn` / `console.error` (routed to stderr) so the caller parses a clean single-line JSON from stdout.

Documented CLI flags (v0.2.7): `--headless`, `--connect`, `--help`.

**Undocumented aspects** of the upstream CLI (may require wrapper workarounds or upstream PRs):

- Exit codes on script throw or timeout — wrap with an `AbortController` and a timeout on the caller side.
- No native script timeout flag — caller enforces a wall-clock limit and kills the process.
- No multi-script chaining in a single invocation — caller spawns per test.
- No `--script <file>` or `--input <file>` flag — scripts must come via stdin.

If any of these block a Studio use case, open an issue upstream
(https://github.com/SawyerHood/dev-browser/issues) before adding a workaround;
the project accepts external contributions.

## Invocation (Mode B — Claude Code plugin)

Once the plugin is installed, Claude uses the nested commands directly — no
separate CLI invocation is needed. Refer to the upstream `SKILL.md`
(loaded via `/plugin install`) for the exact command names; they are
controlled by the plugin and may evolve independently of this file.

## Safety model

- Scripts run in a **QuickJS WASM sandbox** — no direct access to host
  filesystem (beyond `~/.dev-browser/tmp/`) and no direct network calls
  outside the browser context.
- The controlled Chromium runs with the user's normal permissions when
  `--connect` is used against a real Chrome instance. Sensitive pages
  (banking, email, internal admin) are therefore reachable — do not activate
  on pages that contain credentials unless the user has explicitly authorized it.
- Mode A (`--headless`) launches a disposable Chromium with no persisted
  profile, so it is safe to invoke from Phase 5 without user approval per run.

## Relationship to SmartStack Studio

dev-browser is the **test engine of Phase 5** (`skills/development/testing/ui-test/`)
and a **complement** to the other Studio dev skills for exploratory debugging:

- After `scaffold-component` generates a new page, Phase 5 uses dev-browser
  to render it in Chromium and verify the full CRUD flow against a live backend.
- After `validate-frontend-routes` reports a missing route, Claude can use
  the plugin (mode B) in the chat to navigate the offending URL and capture
  the 404.
- During BA, after the user generates a mock UI, the plugin can preview it
  in Chrome and iterate on the design.
