RepoPilotOpen in app →

browserbase/stagehand

The SDK For Browser Agents

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 12 active contributors
  • Distributed ownership (top contributor 18% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the “Healthy” badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/browserbase/stagehand)](https://repopilot.app/r/browserbase/stagehand)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/browserbase/stagehand on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: browserbase/stagehand

Generated by RepoPilot · 2026-05-06 · Source

Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/browserbase/stagehand shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

Verdict

GO — Healthy across the board

  • Last commit today
  • 12 active contributors
  • Distributed ownership (top contributor 18% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live browserbase/stagehand repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/browserbase/stagehand.

What it runs against: a local clone of browserbase/stagehand — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in browserbase/stagehand | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>browserbase/stagehand</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of browserbase/stagehand. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/browserbase/stagehand.git
#   cd stagehand
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of browserbase/stagehand and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "browserbase/stagehand(\\.git)?\\b" \\
  && ok "origin remote is browserbase/stagehand" \\
  || miss "origin remote is not browserbase/stagehand (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "packages/core/src" \\
  && ok "packages/core/src" \\
  || miss "missing critical file: packages/core/src"
test -f "packages/cli/src/index.ts" \\
  && ok "packages/cli/src/index.ts" \\
  || miss "missing critical file: packages/cli/src/index.ts"
test -f "packages/core/examples/example.ts" \\
  && ok "packages/core/examples/example.ts" \\
  || miss "missing critical file: packages/core/examples/example.ts"
test -f "package.json" \\
  && ok "package.json" \\
  || miss "missing critical file: package.json"
test -f ".github/workflows/ci.yml" \\
  && ok ".github/workflows/ci.yml" \\
  || miss "missing critical file: .github/workflows/ci.yml"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/browserbase/stagehand"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Stagehand is a TypeScript browser automation framework that combines AI-driven navigation with imperative code control, allowing developers to automate web interactions using natural language prompts alongside traditional programming. It solves the brittle nature of selector-based automation (Selenium, Playwright) and the unpredictability of pure AI agents by letting developers choose when to use each—AI for exploration, code for repeatability. Monorepo managed with Turbo (package.json scripts coordinate builds across packages). Core logic in packages/core, CLI wrapper in packages/cli, multiple server variants (v3, v4, SEA single-executable-app builds), and changesets for versioning. GitHub Actions orchestrate CI (ci.yml), releases (release.yml, release-cli.yml), and specialized workflows (claude.yml for AI integration, feature-parity.yml for compatibility testing).

Who it's for

Full-stack developers and automation engineers building production web scrapers, RPA workflows, and integration tests who need reliable, maintainable browser automation that can handle dynamic or unfamiliar web UIs without writing fragile CSS selectors.

Maturity & risk

Actively developed with strong maturity signals: monorepo structure with multiple packages, comprehensive CI/CD pipelines (.github/workflows/), test suites across core/e2e/server/evals, and recent changesets indicating ongoing releases. Multiple server implementations (v3, v4, SEA builds) suggest production usage, though the volume of recent feature PRs indicates the API is still evolving.

Medium risk: fast-moving API surface (multiple changesets for recent updates including CUA model support) means breaking changes are likely between versions. Dependency on external AI models (Claude, OpenAI) and Browserbase cloud service creates runtime coupling. Single monorepo means failures cascade across all packages, but the test coverage and CI rigor (separate local/browserbase/remote test targets) mitigate this.

Active areas of work

Recent changesets indicate active work on CUA model support updates, bug fixes (moody-rules-feel, rude-tips-check), and feature development (cool-parrots-start). Multiple server build workflows (stagehand-server-v3/v4, SEA builds) suggest infrastructure improvements. External contributor workflows exist, indicating growing community.

Get running

git clone https://github.com/browserbase/stagehand.git
cd stagehand
pnpm install
pnpm build
pnpm test:core:local

Use pnpm (not npm/yarn) based on package.json. Set STAGEHAND_BROWSER_TARGET=local for local testing without Browserbase cloud.

Daily commands:

pnpm build          # Build all packages
pnpm dev            # Start dev servers (runs turbo dev)
pnpm example -- <name>  # Run examples from packages/core
pnpm test:core:local    # Run core tests locally (no cloud)
pnpm test:e2e:local     # Run E2E tests locally

Map of the codebase

  • packages/core/src — Core SDK implementation containing the Browser, Agent, and Stagehand abstractions that all automation logic depends on
  • packages/cli/src/index.ts — CLI entry point that orchestrates local browser discovery, connection strategies, and server lifecycle management
  • packages/core/examples/example.ts — Primary reference implementation demonstrating the standard SDK usage pattern and integration points
  • package.json — Monorepo workspace configuration defining all package dependencies and shared build/test orchestration via Turbo
  • .github/workflows/ci.yml — Primary CI pipeline validating build, tests, and linting across all packages; blocks merge on failures
  • packages/core/package.json — Core SDK package definition with all dependencies required for browser automation and LLM integration
  • eslint.config.mjs — Shared linting configuration enforced across the monorepo; defines code standards all contributors must follow

How to make changes

Add a new Browser Automation Example

  1. Create a new TypeScript file in packages/core/examples/ following the naming pattern (e.g., my-feature-example.ts) (packages/core/examples/my-feature-example.ts)
  2. Import Stagehand from the core package and initialize with required config (apiKey, model, or localBrowserTarget) (packages/core/examples/my-feature-example.ts)
  3. Use stagehand.page.goto() or agent.act() to automate your workflow; reference example.ts for patterns (packages/core/examples/example.ts)
  4. Test locally with cd packages/core && pnpm run example -- ./examples/my-feature-example.ts (packages/core/package.json)

Add Support for a New LLM Provider

  1. Create a new integration example in packages/core/examples/custom-client-{provider}.ts mirroring the OpenAI pattern (packages/core/examples/custom-client-openai.ts)
  2. Implement a custom client class that extends or adapts the provider's SDK to match Stagehand's expected interface (act, observe, etc.) (packages/core/examples/custom-client-openai.ts)
  3. Pass your custom client to Stagehand initialization via the config object (see example.ts for usage pattern) (packages/core/examples/example.ts)
  4. Add integration tests in packages/core/tests/ and document in README.md (packages/core/README.md)

Add a New CLI Command or Connection Strategy

  1. Add command handler in packages/cli/src/index.ts following existing mode/strategy patterns (local-strategy, local-cdp-discovery) (packages/cli/src/index.ts)
  2. Implement connection strategy file in packages/cli/src/{strategy-name}.ts (e.g., remote-strategy.ts) (packages/cli/src/local-strategy.ts)
  3. Export and register strategy in the main CLI dispatcher; handle WebSocket resolution via resolve-ws.ts (packages/cli/src/resolve-ws.ts)
  4. Add tests in packages/cli/tests/ and validate with pnpm run test:cli (packages/cli/tests/cli.test.ts)

Update Monorepo Dependencies or Add New Package

  1. For package updates, modify packages/core/package.json or packages/cli/package.json directly; root package.json uses Turbo only (packages/core/package.json)
  2. Run pnpm install from root to update lockfile; Turbo will validate build and test across all packages (package.json)
  3. For new packages, create packages/{name}/ with its own package.json, src/, tests/, and tsconfig.json; register in root package.json workspace array (packages/cli/package.json)
  4. Run pnpm run build and pnpm run test to ensure monorepo health (package.json)

Why these technologies

  • TypeScript — Type safety critical for LLM integration APIs, complex DOM abstractions, and multi-package monorepo coordination
  • Turbo — Monorepo build orchestration across core SDK, CLI, and server packages with cached task outputs and parallel builds
  • Chrome DevTools Protocol (CDP) — Low-level browser control enabling programmatic navigation, screenshot capture, and DOM introspection independent of browser driver
  • Vitest + Playwright — Fast, ESM-native test runner with full browser automation support for E2E and integration testing
  • Vercel AI SDK / LangChain — Unified abstraction over multiple LLM providers (OpenAI, Anthropic, local models) with streaming and tool-use support
  • pnpm — Efficient monorepo package management with workspace linking and strict dependency resolution

Trade-offs already made

  • Browser abstraction layer (not tied to single driver)

    • Why: Support diverse deployment scenarios (local Puppeteer, remote Browserbase, Playwright, Patchright)
    • Consequence: Additional API adaptation layer; custom clients must implement expected interface (act, observe, page management)
  • L

    • Why: undefined
    • Consequence: undefined

Traps & gotchas

Must set STAGEHAND_BROWSER_TARGET (local, browserbase, or remote) to run tests—defaults may fail silently. Requires API keys for Claude/OpenAI (inferred from .env.example). Browserbase integration requires account/credentials for cloud testing. Turbo is the build coordinator; running tsc or jest directly in a subdirectory may skip workspace linking. The repo uses pnpm workspaces exclusively—npm/yarn will break. Pre-commit hooks (Husky) enforce formatting; failing to run pnpm prepare on first setup breaks git commits.

Architecture

Concepts to learn

  • Browser Instrumentation & Action Tracing — Stagehand must observe DOM changes and user actions to bridge AI intent with browser state; understanding how it logs/traces actions is critical for debugging AI decisions
  • Prompt Engineering for Browser Tasks — The quality of natural language automation depends on how prompts are constructed and contextualized with page state; this is core to Stagehand's 'choose AI vs code' model
  • LLM Multi-Model Abstraction — Stagehand supports Claude and OpenAI interchangeably; understanding how to abstract different LLM APIs lets you add new model providers or handle fallbacks
  • Monorepo Workspace Management with Turbo — The entire build, test, and release pipeline depends on Turbo's task orchestration; misconfiguring turbo.json breaks incremental builds across packages
  • Headless Browser Automation & Session Management — Stagehand must manage browser lifecycle, context isolation, and state cleanup across distributed sessions (local, cloud, remote); session leaks or state bleeding causes flaky tests
  • Semantic Versioning with Changesets — Every PR must add a changeset file (.changeset/*.md) to declare breaking changes, features, or fixes; this drives automated release notes and version bumps
  • E2E Test Parameterization (Local vs Cloud vs Remote) — Tests run against three targets (STAGEHAND_BROWSER_TARGET), each with different failure modes; understanding target-specific setup prevents false positives in CI

Related repos

  • browserbase/stagehand-python — Official Python port of Stagehand; teams using Python need this companion implementation
  • playwright/playwright — Underlying browser control library that Stagehand wraps; understanding Playwright APIs helps debug browser interactions
  • anthropic-ai/claude-sdk-ts — Claude API SDK used for AI agent reasoning in Stagehand; required for extending LLM integration
  • browserless/browserless — Alternative cloud browser provider; Stagehand can integrate with it as a Browserbase alternative
  • OpenAI/openai-node — OpenAI SDK used as fallback LLM provider in Stagehand for multi-model agent support

PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for CLI local CDP discovery and WebSocket resolution

The CLI package has test files (packages/cli/tests/) but local-cdp-discovery.test.ts and resolve-ws.test.ts are minimal or potentially missing comprehensive coverage. These are critical for users connecting to local browsers. Adding robust tests would ensure the local strategy works reliably across different development environments and prevents regressions.

  • [ ] Review packages/cli/tests/local-cdp-discovery.test.ts for edge cases (multiple browsers running, port conflicts, CDP discovery timeouts)
  • [ ] Review packages/cli/tests/resolve-ws.test.ts for WebSocket URL parsing edge cases (IPv6, custom ports, authentication)
  • [ ] Add tests for error handling scenarios in packages/cli/src/local-strategy.ts
  • [ ] Ensure test coverage for packages/cli/src/local-cdp-discovery.ts with mocked browser processes

Add GitHub Action to validate changesets before release

The repo uses changesets (visible in .changeset/ directory) for versioning but there's no CI workflow to validate that PRs include proper changeset files. This prevents accidental releases without proper changelog entries. Adding a pre-release validation action would catch missing changesets early.

  • [ ] Create .github/workflows/validate-changesets.yml that runs on pull_request events
  • [ ] Use changesets CLI to verify that modified packages have corresponding .changeset/*.md files
  • [ ] Fail the check if files are modified in packages/* but no changeset entry exists (with exceptions for docs-only changes)
  • [ ] Reference the official changesets validation pattern in the workflow

Add cross-platform browser launch verification tests for SEA (Single Executable Archive) builds

The repo has GitHub Actions for SEA builds (stagehand-server-v3-sea-build.yml, stagehand-server-v4-sea-build.yml) and a verify-chromium-launch action, but there's no dedicated test suite validating that SEA bundles can successfully launch browsers on Windows, macOS, and Linux. This is critical for users relying on self-contained binaries.

  • [ ] Create packages/core/tests/sea-chromium-launch.test.ts to validate SEA browser launches
  • [ ] Add platform-specific tests (Windows PE, macOS Mach-O, Linux ELF binary verification)
  • [ ] Integrate tests into .github/workflows/stagehand-server-v4-sea-build.yml to run post-build
  • [ ] Test that bundled Chromium can connect via CDP and respond to basic commands in each environment

Good first issues

  • Add missing unit test coverage for action preview/execution flow in packages/core (test files likely incomplete given the test:core script exists but file count is low relative to TS lines)
  • Document the browser target configuration (STAGEHAND_BROWSER_TARGET=local vs browserbase vs remote) in a new CONTRIBUTING.md, since .env.example hints at this but no guide exists
  • Create an example in packages/examples showing how to chain natural language prompts with imperative code assertions (README mentions 'choose when to write code vs. natural language' but examples may be minimal)

Top contributors

Recent commits

  • f437f73 — fix: preserve OOPIF frame registry parent edge (#2077) (monadoid)
  • 1fa9613 — [STG-1808] Use STAGEHAND_API_URL for Stagehand API client (#2040) (monadoid)
  • ff1f1c3 — Remove old trace (#2075) (miguelg719)
  • 2eb9416 — Evals v2 (#2011) (miguelg719)
  • a87c1fc — default agent to hybrid mode (#2047) (tkattkat)
  • 9ff70dd — [chore] update supported CUA models (#2064) (#2065) (miguelg719)
  • 98cdd20 — Release @browserbasehq/browse-cli@0.6.0 (#1948) (github-actions[bot])
  • 0382005 — Remove docs changeset release metadata (#2057) (monadoid)
  • e87f167 — feat(cli): emit Page.lifecycleEvent in browse cdp (#2056) (derekmeegan)
  • ed4db53 — [STG-1859] fix(cli): use exact DevToolsActivePort websocket path (#2049) (shrey150)

Security observations

  • High · Multiple API Keys in Environment Configuration — .env.example. The .env.example file exposes the structure and names of sensitive API keys including OPENAI_API_KEY, ANTHROPIC_API_KEY, BROWSERBASE_API_KEY, BRAINTRUST_API_KEY, CEREBRAS_API_KEY, and GROQ_API_KEY. While the example file contains empty strings, this serves as a template for developers and could lead to accidental commits of actual credentials if .env files are not properly gitignored. Fix: 1) Ensure .env files are in .gitignore (verify existence). 2) Use a secrets management system (e.g., GitHub Secrets, HashiCorp Vault). 3) Implement pre-commit hooks to prevent credential commits. 4) Document the required environment variables separately without exposing examples.
  • Medium · Husky Pre-commit Hook Present — .husky/pre-commit. The repository includes a .husky/pre-commit hook, which is good practice. However, the actual content of this hook is not visible in the provided file structure. If this hook is weak or misconfigured, it may not effectively prevent credential leakage or other security issues from being committed. Fix: Verify that the pre-commit hook includes checks for: 1) Secrets detection (using tools like detect-secrets or git-secrets), 2) Linting and formatting standards, 3) File permission validation. Ensure the hook is enforced across all developers.
  • Medium · Monorepo with Multiple Packages - Dependency Management Risk — packages/ (multiple packages: cli, core, server, etc.). This is a monorepo (turbo workspace) with multiple packages (cli, core, server). Managing dependencies across multiple packages increases the risk of version mismatches, vulnerable transitive dependencies, and inconsistent security patches across the workspace. Fix: 1) Implement automated dependency scanning (e.g., Dependabot, Snyk). 2) Use consistent dependency versions across the workspace via pnpm workspaces. 3) Regularly audit dependencies with 'npm audit' or 'pnpm audit'. 4) Lock file (pnpm-lock.yaml) should be committed to prevent dependency injection attacks.
  • Medium · CI/CD Workflow Security - External Contributor PRs — .github/workflows/external-contributor-pr.yml. The repository has a workflow for 'external-contributor-pr.yml' which handles pull requests from external contributors. This workflow may have elevated privileges that could be exploited if not properly configured. The presence of separate workflows for internal and external PRs suggests potential security concerns around untrusted code execution. Fix: 1) Ensure external PR workflows run with minimal permissions (read-only). 2) Avoid running tests or builds with access to secrets for external PRs. 3) Require manual approval before merging external PRs. 4) Use 'pull_request_target' carefully and validate all inputs. 5) Review GitHub Actions for credential exposure.
  • Medium · Browser Automation Framework - XSS Risk in Web Interactions — packages/core/src/. Stagehand is a browser automation framework that interacts with web pages. If the framework evaluates or processes JavaScript from untrusted sources or uses dangerouslySetInnerHTML patterns in any internal rendering, it could introduce XSS vulnerabilities. Fix: 1) Validate and sanitize all user-supplied data before injecting into the browser context. 2) Avoid executing arbitrary JavaScript. 3) Use Content Security Policy (CSP) headers where applicable. 4) Ensure DOM interactions use safe APIs (e.g., textContent instead of innerHTML). 5) Audit packages/core examples for unsafe patterns.
  • Low · Release Process Automation - Potential Credential Exposure — .github/workflows/release*.yml. Multiple release workflows exist (release.yml, release-cli.yml, stagehand-server-v3/v4-release.yml) that may publish packages to npm or other registries. These workflows could expose credentials if npm tokens or API keys are not properly managed. Fix: 1) Use GitHub's native secrets management for npm tokens. 2) Rotate credentials regularly. 3) Use short-lived tokens where possible. 4) Audit workflow permissions - they should only have 'write' access to the specific registry. 5) Enable artifact attestation for supply chain security.
  • Low · SEA Build Process - — undefined. undefined Fix: undefined

LLM-derived; treat as a starting point, not a security audit.

Where to read next


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · browserbase/stagehand — RepoPilot