From zero to bashing browsers

A ten-minute tour of the CLI, then 14 hands-on scenarios against real public sites — beginner to advanced. Every command is copy-paste runnable.

The guided tour

1

Install in one line

BrowserBash is a natural-language browser automation CLI: you write a plain-English objective, an AI agent drives a real Chrome browser and returns structured results. Install it globally from npm. You need Node 18 or newer and Google Chrome stable on your machine.

npm install -g browserbash-cli
browserbash --version
2

Your first run

Hand browserbash run an objective in plain English and watch it drive the browser. If you want a value back, end the objective with store ... as 'name' and the captured value is returned in the final state. Add --headless to hide the browser window and --timeout to cap the run in seconds.

browserbash run "Open https://news.ycombinator.com and store the top story title as 'top_story'"

# no visible window, give up after 90 seconds
browserbash run "Open https://example.com and store the heading as 'h1'" --headless --timeout 90
3

Pick a brain: Ollama, Anthropic, or OpenRouter

By default BrowserBash thinks with a local Ollama model: free, open source, no API keys, just have Ollama running. Set ANTHROPIC_API_KEY and it uses Claude instead. For everything else there is OpenRouter: grab a key at openrouter.ai/keys, export OPENROUTER_API_KEY, and pass --model openrouter/<vendor>/<model>. One flag swaps between hundreds of models, so you can trade cost for capability without touching your tests.

# Option 1 — local and free (default): just have Ollama running
ollama pull qwen3
browserbash run "Open https://example.com and store the heading as 'h1'"

# Option 2 — Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
browserbash run "Open https://example.com and store the heading as 'h1'"

# Option 3 — OpenRouter: get a key at openrouter.ai/keys
export OPENROUTER_API_KEY=sk-or-...
browserbash run "..." --model openrouter/anthropic/claude-sonnet-4-6
browserbash run "..." --model openrouter/meta-llama/llama-3.3-70b-instruct
4

Agent mode: NDJSON + exit codes

The --agent flag switches stdout to NDJSON: one JSON object per line, stable schema, built for scripts and AI coding tools. Step events stream as the agent works, then a single run_end event carries the verdict, a summary, the final state with your stored values, and the duration. The process exit code is the verdict itself, so callers never have to parse output.

browserbash run "<objective>" --agent --headless --timeout 120

# progress events, one per step
{"type":"step","step":1,"status":"passed","action":"navigate","remark":"..."}

# terminal event
{"type":"run_end","status":"passed|failed|error|timeout","summary":"...","final_state":{...},"duration_ms":...,"test_url":"..."}

# exit codes: 0 passed · 1 failed · 2 error · 3 timeout
5

Markdown test files

Tests are plain Markdown files ending in _test.md: committable, reviewable, and readable by anyone on the team. Each list item is one step, {{placeholders}} work everywhere, and you can splice shared steps in with @import ./helpers/login.md. Run a file with browserbash testmd run; after every run a Result.md report is written next to the test file.

mkdir -p .browserbash/tests
cat > .browserbash/tests/login_test.md <<'EOF'
# Login flow

- Open {{base_url}}/login
- Type {{username}} into the email field
- Type {{password}} into the password field and press Enter
- Verify the dashboard heading is visible
- Store the logged-in user name as 'user_name'
EOF

browserbash testmd run .browserbash/tests/login_test.md
# -> writes .browserbash/tests/Result.md next to the test file
6

Variables & secrets

Any {{key}} placeholder in an objective or test step gets substituted at run time. Pass values inline with --variables, from a file with --variables-file, or drop JSON files in ./.browserbash/variables/ (project) and ~/.browserbash/variables/ (global) to load them automatically. Wrap sensitive values as {"value":"...","secret":true} and they are masked as ***** in all logs and NDJSON output.

browserbash run "Log in to {{base_url}} as {{username}} with password {{password}}" \
  --variables '{"base_url":"https://app.example.com","username":"qa@example.com","password":{"value":"hunter2","secret":true}}'

# or keep them in a file
browserbash run "Log in to {{base_url}} as {{username}} with password {{password}}" \
  --variables-file ./staging.vars.json

# secret values never leak — logs show: Type ***** into the password field
7

Run it in CI

Agent mode and exit codes make CI integration trivial: the job fails exactly when the test fails, with zero output parsing. Run headless, set a timeout, and put your LLM key in repo secrets. Pipe the NDJSON to a file if you want step-by-step logs as a build artifact.

# .github/workflows/e2e.yml
name: e2e
on: [push]
jobs:
  smoke:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install -g browserbash-cli
      - run: browserbash testmd run .browserbash/tests/smoke_test.md --agent --headless --timeout 180
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# exit code is the verdict: 0 passed · 1 failed · 2 error · 3 timeout
8

Record the session

Add --record to any run and BrowserBash captures a screenshot and a full session video — on every engine, including the free Stagehand default (the video is stitched from a CDP screencast with ffmpeg, which ships with the CLI). The builtin engine additionally captures a Playwright trace. Recordings are saved locally with the run — view them in the local dashboard (next step) or push them to your cloud dashboard with --upload.

# record a run — screenshot + session video on any engine
browserbash run "Open https://example.com and store the heading as 'h1'" --record

# the recording is saved locally; see it with: browserbash dashboard
9

Your dashboard: local (free) or cloud (optional)

Every run is kept in a private on-disk store. browserbash dashboard opens a free local web dashboard — left panel of runs, main pane with the verdict, extracted values and the recording, side by side, exactly like the hosted one. Nothing leaves your machine. Want history across machines and shareable links? Create a free account at browserbash.com, connect once, and push a run with --upload. It is all free; cloud runs are kept 15 days.

# free, local, no account — opens http://localhost:4477
browserbash dashboard

# run and pop the local dashboard open on this run
browserbash run "Open https://example.com and store the heading as 'h1'" --record --dashboard

# optional cloud: connect once, then push the runs you choose
browserbash connect --key bb_...      # key from browserbash.com/dashboard
browserbash run "..." --record --upload
10

Run on LambdaTest — every run recorded in the cloud

Point --provider lambdatest at LambdaTest's cloud grid and the browser runs on their infrastructure instead of your machine. Every session is automatically recorded on their side: full video, network log, and browser console, all waiting in the LambdaTest Automation dashboard the moment the run ends. BrowserBash also pushes the verdict back, so each session shows up already marked passed or failed, and prints the dashboard link as test_url. One note: cloud grids use the builtin engine, which speaks the Anthropic API — set ANTHROPIC_API_KEY (Ollama and OpenRouter models stay local-only).

# credentials: lambdatest.com -> Account Settings -> Password & Security
export LT_USERNAME=your_username
export LT_ACCESS_KEY=your_access_key
export ANTHROPIC_API_KEY=sk-ant-...        # cloud grids use the builtin (Anthropic) engine

# or store creds once instead of env vars:
browserbash login --provider lambdatest --username your_username --access-key your_access_key

browserbash run "Open https://www.saucedemo.com, log in as standard_user with password secret_sauce, and store the first product name as 'product'" \
  --provider lambdatest

# run ends with the session link:
#   test_url: https://automation.lambdatest.com/build
# -> open it: video replay, network log, console, and pass/fail status — recorded automatically
11

Run on BrowserStack — video replay on Automate

The same one flag works for BrowserStack: --provider browserstack runs your plain-English objective on BrowserStack Automate. Their dashboard keeps a video recording of the whole session plus the text and network logs, and BrowserBash reports the verdict through the browserstack_executor protocol, so the session is marked passed or failed without you touching anything. Works for single runs and full testmd files alike — your markdown tests gain cloud video replay with zero changes to the test.

# credentials: browserstack.com -> Account & Profile -> Summary (Automate section)
export BROWSERSTACK_USERNAME=your_username
export BROWSERSTACK_ACCESS_KEY=your_access_key
export ANTHROPIC_API_KEY=sk-ant-...        # cloud grids use the builtin (Anthropic) engine

# or: browserbash login --provider browserstack --username ... --access-key ...

# single run on the grid
browserbash run "Open https://news.ycombinator.com and store the top story title as 'top_story'" \
  --provider browserstack

# whole markdown test file on the grid — same file, just add the flag
browserbash testmd run .browserbash/tests/login_test.md --provider browserstack

# test_url: https://automate.browserstack.com/dashboard
# -> video replay + logs per session, already marked passed/failed

14 scenarios, real sites, real verdicts

Each card is a complete exercise: an objective, the exact command, hints if you're stuck, and what a passing run looks like. The exit code is your scoreboard — 0 means Bo approves.

01beginnerextraction

Hello, Browser

Open https://example.com and store the main heading text as 'h1'

The core loop: objective in, verdict and extracted values out.

browserbash run "Open https://example.com and store the main heading text as 'h1'" --headless
02beginnerextraction

Front Page News

Open https://news.ycombinator.com and store the top story title as 'top_story' and its points as 'points'

Extracting multiple values from one page in a single pass.

browserbash run "Open https://news.ycombinator.com and store the top story title as 'top_story' and its points as 'points'" --headless
03beginnerverification

Quote Quality Control

Open https://quotes.toscrape.com, verify there are exactly 10 quotes on the first page, and store the first quote's author as 'author'

Mixing verification and extraction — your first real test.

browserbash run "Open https://quotes.toscrape.com, verify there are exactly 10 quotes on the first page, and store the first quote's author as 'author'" --headless
04beginnerextraction

Judge a Book by Its Cover

Open https://books.toscrape.com and store the title and price of the first book as 'title' and 'price'

Targeting a specific element among many similar ones.

browserbash run "Open https://books.toscrape.com and store the title and price of the first book as 'title' and 'price'" --headless
05intermediatelogin

Secret Agent Login

Open {{base_url}}/login, log in as {{username}} with password {{password}}, and verify the page says 'You logged into a secure area'

Variables, secret masking, and a real login flow.

browserbash run "Open {{base_url}}/login, log in as {{username}} with password {{password}}, and verify the page says 'You logged into a secure area'" --headless --variables '{"base_url":"https://the-internet.herokuapp.com","username":"tomsmith","password":{"value":"SuperSecretPassword!","secret":true}}'
06intermediatee2e

Supermarket Sweep

Open {{base_url}}, log in as {{username}} with password {{password}}, add the Sauce Labs Backpack to the cart, and store the cart badge count as 'cart_count'

A multi-step shop flow: login, action, then state extraction.

browserbash run "Open {{base_url}}, log in as {{username}} with password {{password}}, add the Sauce Labs Backpack to the cart, and store the cart badge count as 'cart_count'" --headless --variables '{"base_url":"https://www.saucedemo.com","username":"standard_user","password":{"value":"secret_sauce","secret":true}}'
07intermediateforms

Form and Function

Open https://httpbin.org/forms/post, fill the customer name with 'Bo Basher', choose a Large pizza, check the cheese topping, submit the form, and verify the response contains 'Bo Basher'

Form controls: text, radio, checkbox, submit — no selectors needed.

browserbash run "Open https://httpbin.org/forms/post, fill the customer name with 'Bo Basher', choose a Large pizza, check the cheese topping, submit the form, and verify the response contains 'Bo Basher'" --headless
08intermediatesearch

Search Party

Open https://duckduckgo.com, search for 'browser automation', and store the title of the first result as 'first_result'

Handling navigation triggered by a search, plus dynamic content.

browserbash run "Open https://duckduckgo.com, search for 'browser automation', and store the title of the first result as 'first_result'" --headless --timeout 120
09advancede2e

Checkout Champion

Open {{base_url}}, log in as {{username}} with password {{password}}, add the Sauce Labs Backpack and Sauce Labs Bike Light to the cart, go to checkout, fill first name 'Bo', last name 'Basher', postal code '94016', finish the order, and store the confirmation header as 'confirmation'

A full e2e purchase: 10+ steps, one English sentence.

browserbash run "Open {{base_url}}, log in as {{username}} with password {{password}}, add the Sauce Labs Backpack and Sauce Labs Bike Light to the cart, go to checkout, fill first name 'Bo', last name 'Basher', postal code '94016', finish the order, and store the confirmation header as 'confirmation'" --headless --timeout 180 --max-steps 40 --variables '{"base_url":"https://www.saucedemo.com","username":"standard_user","password":{"value":"secret_sauce","secret":true}}'
10advancedinteractions

Dropdown Dexterity

Open {{base_url}}/dropdown, select 'Option 2' from the dropdown, then open {{base_url}}/checkboxes, check both checkboxes, and verify both are checked

Native form widgets across multiple pages in one run.

browserbash run "Open {{base_url}}/dropdown, select 'Option 2' from the dropdown, then open {{base_url}}/checkboxes, check both checkboxes, and verify both are checked" --headless --variables '{"base_url":"https://the-internet.herokuapp.com"}'
11advancedextraction

Price Patrol

Open https://books.toscrape.com, navigate to the Travel category, store the number of books shown as 'count' and the price of the most expensive book on the page as 'max_price'

Navigation plus comparative reasoning over page data.

browserbash run "Open https://books.toscrape.com, navigate to the Travel category, store the number of books shown as 'count' and the price of the most expensive book on the page as 'max_price'" --headless --timeout 120
12advancedtesting

Markdown Test Drive

Write a committable *_test.md file and run it with testmd — your first reviewable test artifact

Tests as reviewable markdown files your whole team can read.

cat > hn_test.md <<'EOF' # Hacker News smoke - Open https://news.ycombinator.com - Verify the page has loaded and stories are visible - Store the title of the first story as 'top_story' - Store the points of the first story as 'top_points' EOF browserbash testmd run ./hn_test.md --headless
13advancedcloud

Cloud Replay: LambdaTest

Run the SauceDemo cart flow on LambdaTest's grid and watch the full video replay in their Automation dashboard

Cloud execution: every run auto-recorded with video, no local browser.

export LT_USERNAME=your_username export LT_ACCESS_KEY=your_access_key export ANTHROPIC_API_KEY=sk-ant-... browserbash run "Open https://www.saucedemo.com, log in as standard_user with password secret_sauce, add the Sauce Labs Backpack to the cart, and store the cart badge count as 'cart_count'" --provider lambdatest --name "saucedemo cart"
14advancedcloud

Cloud Replay: BrowserStack

Run a markdown test file on BrowserStack Automate and get a video replay of every step, marked passed or failed

The same reviewable test file, now with cloud video evidence per run.

cat > grid_login_test.md <<'EOF' # Secure area login (on the grid) - Open https://the-internet.herokuapp.com/login - Log in as tomsmith with password SuperSecretPassword! - Verify the page says 'You logged into a secure area' EOF export BROWSERSTACK_USERNAME=your_username export BROWSERSTACK_ACCESS_KEY=your_access_key export ANTHROPIC_API_KEY=sk-ant-... browserbash testmd run ./grid_login_test.md --provider browserstack