How to Migrate From Browser Use to Stagehand
Browser Use is a Python-native AI browser automation library that takes a natural-language-first approach: you describe a task, the agent figures out what to click, fill, and extract. It's powerful for exploratory automation where the exact steps aren't fully known in advance. The challenge is predictability. When you need a production automation that runs 500 times a day on a specific workflow, the "figure it out" model introduces variance. The agent occasionally takes an unexpected path, gets confused by a UI change, or produces output in an inconsistent format.
Stagehand takes a different position. It's TypeScript-first, built on Playwright, and designed for the case where a developer wants AI assistance for the ambiguous parts of browser automation while keeping deterministic control over the parts that need to be reliable. The three core methods, act, extract, and observe, give you a structured API that's predictable enough to test, debug, and trust in production. Teams moving from Browser Use typically cite two reasons: they want TypeScript (or their codebase is already TypeScript), and they want structured extraction results with a typed schema rather than free-form text output.
What's actually different
The philosophical difference is where AI responsibility ends and developer responsibility begins. Browser Use places most of the decision-making with the AI model; you describe the goal and the agent navigates. Stagehand places the navigation structure with the developer; you write the steps and use AI for the parts that need perception (extracting unstructured data, identifying the right element in an ambiguous context).
| Dimension | Browser Use | Stagehand |
|---|---|---|
| Primary language | Python | TypeScript / JavaScript |
| Underlying engine | Playwright (Python) | Playwright |
| Automation model | Task-driven (LLM plans steps) | Code-driven (dev writes steps, AI assists) |
| Extraction | Free-form AI output | Typed schema (Zod) |
| Action API | Natural language instructions | act(), extract(), observe() |
| Debugging | LLM trace logs | Standard Playwright + typed data |
| Testing | Harder (nondeterministic) | Standard TypeScript testing |
| Reliability | Variable | More consistent |
The typed extraction difference is significant for production use. In Stagehand, when you extract data from a page, you define a Zod schema. The extraction result is validated against that schema, so you get TypeScript types and runtime validation. If the page changes and the extraction no longer matches your schema, you get a clear error rather than silently wrong data.
The observe method is worth understanding separately. It takes a description of an action and returns the Playwright action that would execute it, without executing it. This lets you build adaptive automation that can handle UI changes by observing the current state of the page and choosing the right action, rather than hardcoding a CSS selector that breaks when the page changes.
Mapping your existing automation
Browser Use and Stagehand don't share a common vocabulary because their models are different, but the concepts map cleanly enough.
A Browser Use task (a natural language instruction passed to the agent) breaks down into explicit Stagehand steps. If your Browser Use task was "fill out the contact form with name John Smith and submit it," in Stagehand you'd write code that calls page.act("fill in the name field with John Smith") and page.act("click the submit button"). The AI handles the ambiguity in each step; you control the sequence.
Browser Use's agent.run() loop maps to a regular async function in Stagehand where you call a sequence of page.act(), page.extract(), and page.observe() calls. You orchestrate the flow; Stagehand handles the AI-powered interaction.
Browser Use's data extraction (where the agent outputs what it found) maps to Stagehand's page.extract() with a Zod schema. Define the fields you want, their types, and their descriptions. Stagehand returns a validated, typed object.
// Example: extracting structured data in Stagehand
import { z } from "zod";
const productSchema = z.object({
name: z.string().describe("Product name"), price: z.number().describe("Price in dollars"), inStock: z.boolean().describe("Whether the product is in stock"),
});
const product = await page.extract({
instruction: "Extract the product details from this page", schema: productSchema,
});
// product is typed: { name: string, price: number, inStock: boolean }
Browser Use's form filling maps to repeated page.act() calls or direct Playwright calls for known, stable inputs. For cases where the field identifier might change, page.act("type X into the email field") handles the ambiguity. For stable fields, a direct page.fill('#email', '[email protected]') call via Playwright is faster and more reliable.
Multi-page Browser Use flows map to sequential Stagehand operations with explicit navigation. Call page.goto() for URL navigation (direct Playwright), page.act() for AI-assisted clicks on links or buttons, and structure the flow with regular TypeScript control flow: loops, conditionals, try-catch.
The actual migration steps
Step 1: Set up a Stagehand project. Stagehand is an npm package (@browserbasehq/stagehand). Create a TypeScript project, install the package, and set up your LLM API key (OpenAI or Anthropic). The Stagehand README has a minimal setup that gets you to a working browser session in a few minutes.
Step 2: Translate your Browser Use tasks to Stagehand step sequences. Go through each Browser Use automation and break the natural language task into explicit steps. For each step, decide: is this a direct Playwright action (navigation, known-stable selectors), an act() call (AI-powered interaction with ambiguous elements), or an extract() call (pulling structured data from the page)?
Step 3: Define Zod schemas for all extractions. For every place where your Browser Use automation extracted data, define a Zod schema describing the output. Be specific in the field descriptions; they guide the extraction AI. Test the schema against a few example pages to validate it captures what you need.
Step 4: Write TypeScript tests. This is the benefit you couldn't have with Browser Use. Because Stagehand's output is typed and deterministic for extraction, you can write unit tests that validate schema shapes and integration tests that run the automation and check the output. Set up a test suite before considering the migration complete.
Step 5: Validate against your production targets. Run your Stagehand automations against the same URLs and pages your Browser Use automation handled. Compare the extracted data and the actions taken. For any page where behavior diverges, inspect the Stagehand trace and refine your act() instructions or schemas.
Step 6: Replace Browser Use scripts in production. Once validation passes, swap out the Browser Use script for the Stagehand equivalent in your production pipeline. Monitor the first few production runs closely and check that extracted data matches expected schemas.
Gotchas you'll hit
The migration requires writing more code. Browser Use's appeal is minimal code: describe the task, get a result. Stagehand requires explicit step sequences. For a 10-step automation, you're writing 20-30 lines of TypeScript instead of one natural language prompt. This is the tradeoff for reliability.
act() call granularity matters. Instructions like "complete the checkout process" are too broad for a single act() call. Stagehand works best with focused, single-action instructions: "click the Add to Cart button," "select Standard Shipping from the dropdown." If an act() call fails or produces unexpected behavior, splitting it into smaller calls usually fixes it.
JavaScript-rendered pages and dynamic content. Playwright handles these natively, but you need to manage waits explicitly. Browser Use's agent often handles waiting automatically by observing page state. In Stagehand/Playwright, you use page.waitForSelector(), page.waitForURL(), or Stagehand's observe() to check the page state before acting.
Stagehand's observe() isn't free. Every call to act(), extract(), and observe() makes an LLM API call. For automations that run frequently, the API cost scales linearly with the number of AI-powered steps per run. Use direct Playwright calls for actions where selectors are stable and known; reserve act() for genuinely ambiguous cases.
Python tooling doesn't carry over. If your Browser Use automation is part of a larger Python pipeline, integrating Stagehand means either adding a Node.js subprocess, calling Stagehand via an HTTP API, or rewriting the surrounding pipeline in TypeScript. For pure-Python teams, this is a real infrastructure change.
Browser sessions and authentication. Browser Use manages sessions as part of the agent loop. In Stagehand, you manage sessions through Playwright's browser context. Persisting authentication cookies or localStorage state between runs requires explicit handling with Playwright's context storage APIs.
When NOT to switch
Browser Use is the better choice in some situations.
If you're in a Python-only environment and your team has no TypeScript experience, the language switch is a significant barrier. Browser Use's Python API is mature and integrates naturally with Python data pipelines.
If your automation is exploratory rather than production: testing a site's behavior, researching a workflow, or doing one-off data collection, Browser Use's high-level task model is faster to get results. You don't need to define schemas or write step sequences for a one-time task.
If the workflows are genuinely open-ended and the sequence of steps is unknown in advance, Browser Use's autonomous agent model handles that better. Stagehand assumes you know the sequence and use AI for the ambiguous elements within it.
The migration from Browser Use to Stagehand is primarily a bet on reliability and TypeScript DX over conciseness. You write more code, but the code is testable, the outputs are typed, and production runs are more predictable.
Start with one automation that currently causes occasional failures or inconsistent output in Browser Use. Rebuild it in Stagehand with explicit step sequences and a Zod extraction schema. The difference in reliability will be apparent in the first week of production runs.