---
title: CLI Reference
description: All CLI commands, flags, and usage patterns for controlling Chrome from the terminal.
icon: lucide:terminal
---

The Playwriter CLI sends Playwright code to your browser through a local WebSocket relay. Every command connects to the relay on `localhost:19988`, which the extension also connects to. No servers, no accounts.

## Execute code

```bash
playwriter -s <sessionId> -e "<code>"
```

The `-s` flag specifies a **session ID** (required). Get one with `playwriter session new`. The `-e` flag takes JavaScript code that runs in a sandboxed Playwright environment.

<Aside>
<Note>
Always use **single quotes** for `-e` to prevent bash from interpreting `$`, backticks, and `\` in your JS code.
</Note>
</Aside>

```bash
# Navigate
playwriter -s 1 -e 'await page.goto("https://example.com")'

# Click
playwriter -s 1 -e 'await page.locator("button").click()'

# Get title
playwriter -s 1 -e 'console.log(await page.title())'

# Screenshot
playwriter -s 1 -e 'await page.screenshot({ path: "/tmp/shot.png", scale: "css" })'

# Accessibility snapshot
playwriter -s 1 -e 'console.log(await snapshot({ page }))'
```

### Multiline code

Use a **heredoc** for complex scripts:

```bash
playwriter -s 1 -e "$(cat <<'EOF'
const links = await page.$$eval('a', els => els.map(e => e.href));
console.log('Found', links.length, 'links');
const text = await page.locator('body').innerText();
const price = text.match(/\$[\d.]+/);
EOF
)"
```

Or `$'...'` syntax for simpler multiline:

```bash
playwriter -s 1 -e $'
const title = await page.title();
const url = page.url();
console.log({ title, url });
'
```

### Execute from file

For longer scripts, use `-f`:

```bash
playwriter -s 1 -f script.js
```

The file runs in the same sandbox as `-e` with all context variables available.

## Session management

Each session is an **isolated sandbox** with its own `state` object. Browser tabs are shared across sessions, but state is not.

```bash
playwriter session new              # create sandbox, outputs id (e.g. 1)
playwriter session list             # show sessions + state keys
playwriter session reset <id>       # reconnect if connection is stale
playwriter session delete <id>      # remove session and clear state
```

### Direct CDP connection

Connect to Chrome's DevTools Protocol without the extension:

```bash
playwriter session new --direct
```

This requires the user to accept a debugging approval dialog in Chrome. Enable debugging first at `chrome://inspect/#remote-debugging` or launch Chrome with `--remote-debugging-port=9222`.

**Limitations:** screen recording is unavailable in direct mode.

## Browser management

```bash
playwriter browser start              # auto-find and launch Chrome for Testing
playwriter browser start /path/to/bin # launch specific binary
playwriter browser list               # list all available browsers
```

`browser start` launches Chrome with recording flags enabled and the bundled extension pre-loaded.

## Remote connection

Connect to a relay running on another machine:

```bash
playwriter --host https://my-machine-tunnel.traforo.dev --token SECRET session new
playwriter --host https://my-machine-tunnel.traforo.dev --token SECRET -s 1 -e "..."
```

Or with environment variables:

```bash
export PLAYWRITER_HOST=https://my-machine-tunnel.traforo.dev
export PLAYWRITER_TOKEN=SECRET
playwriter session new
playwriter -s 1 -e 'await page.goto("https://example.com")'
```

See [Remote Access](./remote-access.mdx) for the full guide.

## Serve command

Start the relay server explicitly (useful for remote access and Docker):

```bash
playwriter serve --token MY_SECRET        # binds to 0.0.0.0, requires --token
playwriter serve --host localhost         # binds to 127.0.0.1, no token needed
playwriter serve --token MY_SECRET --replace  # kill existing server first
```

The relay starts automatically when you use the CLI locally. Use `serve` explicitly when you need it running persistently for remote clients.

## Other commands

```bash
playwriter logfile                        # print log file path
playwriter skill                          # print agent instructions
playwriter completions install            # install shell completions (zsh/bash)
```

## Global flags

| Flag | Description |
|---|---|
| `--host <host>` | Remote relay host (or `PLAYWRITER_HOST` env var) |
| `--token <token>` | Auth token (or `PLAYWRITER_TOKEN` env var) |
| `-s, --session <id>` | Session ID (required for `-e` and `-f`) |
| `-e, --eval <code>` | Execute JavaScript and exit |
| `-f, --file <path>` | Execute JavaScript from file |
| `--timeout [ms]` | Execution timeout (default: 10000) |

## Context variables

Code executed with `-e` or `-f` has access to:

| Variable | Description |
|---|---|
| `page` | Default page (may be shared with other agents) |
| `context` | Browser context, access all pages via `context.pages()` |
| `state` | Object persisted between calls within your session |
| `require` | Load Node.js modules (e.g. `require('node:fs')`) |
| `snapshot` | Get accessibility snapshot of a page |
| `getCDPSession` | Send raw CDP commands |
| `createDebugger` | Set breakpoints, step through code |
| `createEditor` | Live-edit page scripts and CSS |
| `recording` | Start/stop screen recording |
| `screenshotWithAccessibilityLabels` | Screenshot with Vimium-style labels |
| `getLatestLogs` | Get browser console logs |
| `getCleanHTML` | Get cleaned HTML from page |
| `getPageMarkdown` | Extract article content as text |
| `waitForPageLoad` | Smart load detection |

See [Agent Reference](./skill.mdx) for the full API documentation.
