skillpack.co
← All solutions

Stagehand

active

AI-native browser automation SDK by Browserbase with natural language selectors and act/extract/observe primitives.

Score 90

Where it wins

TypeScript-native with clean act/extract/observe API

Natural language selectors reduce brittle CSS/XPath dependencies

Official Browserbase backing with cloud browser infrastructure

Where to be skeptical

Smaller community than Browser Use

Tied to Browserbase ecosystem for cloud execution

Newer — less battle-tested in production agent loops

Editorial verdict

Best SDK for building browser automation into products. Three clean primitives (act, extract, observe), v3 dropped Playwright dependency, Cloudflare official integration. New browse-cli shows the team reads the CLI-over-MCP signal correctly.

Videos

Reviews, tutorials, and comparisons from the community.

Tutorial de Testing E2E con IA

midudev·2026-01-23

Stagehand V2: FULLY FREE Browser Use AI Agent! Automate ANYTHING! (Opensource)

WorldofAI·2025-06-13

Automate Your Browser with AI Using StageHand AI Agent

AI LABS·2025-01-21

Related

Public evidence

strong2025-09
Cloudflare official integration for serverless deployments

Cloudflare added native Stagehand support in their Browser Rendering Workers. Major cloud provider integration validates production readiness at scale.

Official Cloudflare documentation integrationCloudflare (major infrastructure company, independent)
moderateSelf-reported2026-02
v3: 44% faster, dropped Playwright dependency, modular drivers

Stagehand v3 dropped the Playwright hard dependency — now supports any CDP-based driver. 44% faster. New browse-cli product (launched Mar 18) shows the team reads the CLI-over-MCP signal correctly.

Major version releaseBrowserbase team (official)
moderate2026-02
NxCode comparison: Stagehand ~75% task completion vs Browser Use ~78%

Independent comparison measured Stagehand at ~75% task completion vs Browser Use ~78%. TypeScript-only (no Python). Auto-caching architecture genuinely differentiated: once AI action succeeds, selector cached and replayed without LLM calls.

Independent tech comparisonNxCode (independent)

Raw GitHub source

GitHub README peek

Constrained peek so you can sanity-check the source material without leaving the site.

<div id="toc" align="center" style="margin-bottom: 0;"> <ul style="list-style: none; margin: 0; padding: 0;"> <a href="https://stagehand.dev"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/browserbase/stagehand/main/media/dark_logo.png" /> <img alt="Stagehand" src="https://raw.githubusercontent.com/browserbase/stagehand/main/media/light_logo.png" width="200" style="margin-right: 30px;" /> </picture> </a> </ul> </div> <p align="center"> <strong>Stagehand is the SDK for browser agents</strong><br> </p> <p align="center"> <a href="https://trendshift.io/repositories/12122" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12122" alt="browserbase%2Fstagehand | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a> </p> <p align="center"> <a href="https://docs.stagehand.dev"><strong>Docs</strong></a> · <a href="https://docs.stagehand.dev/v4/first-steps/quickstart"><strong>Quickstart</strong></a> · <a href="https://github.com/browserbase/stagehand/stargazers"><strong>⭐ Star this repo</strong></a> </p> <p align="center"> <a href="https://github.com/browserbase/stagehand/tree/main?tab=MIT-1-ov-file#MIT-1-ov-file"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/browserbase/stagehand/main/media/dark_license.svg" /> <img alt="MIT License" src="https://raw.githubusercontent.com/browserbase/stagehand/main/media/light_license.svg" /> </picture> </a> <a href="https://discord.gg/stagehand"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/browserbase/stagehand/main/media/dark_discord.svg" /> <img alt="Discord Community" src="https://raw.githubusercontent.com/browserbase/stagehand/main/media/light_discord.svg" /> </picture> </a> <a href="https://deepwiki.com/browserbase/stagehand"> <img alt="Ask DeepWiki" src="https://raw.githubusercontent.com/browserbase/stagehand/main/media/deepwiki.svg" width="156" height="32" /> </a> </p> <p align="center"> <a href="https://stagehand.dev"> <img src="https://raw.githubusercontent.com/browserbase/stagehand/main/media/stagehand-website-banner.png" alt="Stagehand homepage showing browser automation in TypeScript, Python, and Go and a speed comparison with Playwright" width="100%" /> </a> </p>

AI that uses the browser like humans.

Sign in once, keep the session, and pull structured data out the other side.

import { localBrowser, Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod/v4";

// Cookies persist in ./browser-data, so the next run starts already signed in
const browser = await localBrowser.launch({ userDataDir: "./browser-data" });
const stagehand = await Stagehand.create({
  browser,
  model: { modelName: "openai/gpt-5.4-mini", apiKey: process.env.OPENAI_API_KEY },
});

const [page] = await browser.context.pages();
await page.goto("https://app.example.com/login");

// observe() returns real selectors, so credentials never reach the model
const { data: email } = await stagehand.observe("find the email input");
const { data: password } = await stagehand.observe("find the password input");
await page.locator(email[0].selector).fill(process.env.APP_EMAIL!);
await page.locator(password[0].selector).fill(process.env.APP_PASSWORD!);

// act() self-heals when the site redesigns its form
await stagehand.act("click the sign in button");
await stagehand.act("open the billing page");

// extract() returns schema-validated data
const { data } = await stagehand.extract(
  "extract every invoice in the table",
  z.object({
    invoices: z.array(z.object({ number: z.string(), amount: z.number(), paid: z.boolean() })),
  }),
);

console.log(data.invoices);

await stagehand.close();
await browser.close();
<details> <summary><b>Python</b></summary>
import asyncio
import os

from pydantic import BaseModel
from stagehand import Stagehand, local_browser


class Invoice(BaseModel):
    number: str
    amount: float
    paid: bool


class Invoices(BaseModel):
    invoices: list[Invoice]


async def main() -> None:
    # Cookies persist in ./browser-data, so the next run starts already signed in
    browser = await local_browser.launch(user_data_dir="./browser-data")
    try:
        stagehand = await Stagehand.create(
            browser=browser,
            model="openai/gpt-5.4-mini",
            model_api_key=os.environ["OPENAI_API_KEY"],
        )
        try:
            page = (await browser.context.pages())[0]
            await page.goto("https://app.example.com/login")

            # observe() returns real selectors, so credentials never reach the model
            email = await stagehand.observe("find the email input")
            password = await stagehand.observe("find the password input")
            await page.locator(email.data[0].selector).fill(os.environ["APP_EMAIL"])
            await page.locator(password.data[0].selector).fill(os.environ["APP_PASSWORD"])

            # act() self-heals when the site redesigns its form
            await stagehand.act("click the sign in button")
            await stagehand.act("open the billing page")

            # extract() returns schema-validated data
            result = await stagehand.extract(
                "extract every invoice in the table",
                Invoices,
            )
            print(result.data.invoices)
View on GitHub →