Skip to main content

Overview

Stagehand v3 can work seamlessly with Puppeteer, allowing you to use Puppeteer’s Page objects directly with Stagehand’s AI-powered methods like act(), extract(), and observe().

Installation

First, install both Stagehand and Puppeteer:
npm install @browserbasehq/stagehand puppeteer-core

Quickstart

Basic Setup

Connect Puppeteer to Stagehand’s browser instance:
import { Stagehand } from "@browserbasehq/stagehand";
import puppeteer from "puppeteer-core";

const stagehand = new Stagehand({
  env: "LOCAL", // or "BROWSERBASE"
  model: "openai/gpt-5",
});

await stagehand.init();

// Connect Puppeteer to Stagehand's browser
const browser = await puppeteer.connect({
  browserWSEndpoint: stagehand.connectURL(),
  defaultViewport: null,
});

const pages = await browser.pages();
const ppPage = pages[0];

Using Puppeteer Pages with Stagehand

Once connected, you can use Puppeteer’s Page objects with Stagehand’s AI-powered methods:
// Navigate using Puppeteer
await ppPage.goto("https://example.com");

// Use Stagehand's AI methods with the Puppeteer page
await stagehand.act("click the sign in button", { page: ppPage });

const data = await stagehand.extract(
  "extract the page title",
  z.object({ title: z.string() }),
  { page: ppPage }
);

Advanced: Multi-Page Usage

Create and manage multiple Puppeteer pages with Stagehand:
import { Stagehand } from "@browserbasehq/stagehand";
import puppeteer from "puppeteer-core";
import { z } from "zod";

async function multiPageExample() {
  const stagehand = new Stagehand({
    env: "BROWSERBASE",
    model: "openai/gpt-5",
  });

  await stagehand.init();

  // Connect Puppeteer
  const browser = await puppeteer.connect({
    browserWSEndpoint: stagehand.connectURL(),
    defaultViewport: null,
  });

  // Get the first page
  const pages = await browser.pages();
  const ppPage1 = pages[0];

  // Create a second page
  const ppPage2 = await browser.newPage();

  // Navigate both pages
  await ppPage1.goto("https://example.com");
  await ppPage2.goto("https://another-site.com");

  // Use Stagehand on different pages
  await stagehand.act("click the button", { page: ppPage1 });

  const data = await stagehand.extract(
    "extract the title",
    z.object({ title: z.string() }),
    { page: ppPage2 }
  );

  console.log("Extracted from page 2:", data);

  await stagehand.close();
}

Observe + Act Pattern

The recommended pattern for reliable automation:
// Step 1: Observe to find candidate actions
const actions = await stagehand.observe(
  "find the submit button",
  { page: ppPage }
);

// Step 2: Execute the first action
if (actions.length > 0) {
  await stagehand.act(actions[0], { page: ppPage });
}
This pattern helps avoid DOM changes between observation and action execution.

Key Points

  • Connect via WebSocket: Use puppeteer.connect() with stagehand.connectURL() as the browserWSEndpoint
  • Pass the page: Always pass the Puppeteer page object to Stagehand methods using the { page } option
  • Disable viewport: Set defaultViewport: null to use Stagehand’s viewport settings
  • Multi-page support: Create multiple pages with browser.newPage() and pass them to Stagehand methods

Environment Variables

When using Browserbase, set your credentials:
BROWSERBASE_API_KEY=your_api_key
BROWSERBASE_PROJECT_ID=your_project_id
For OpenAI (or other providers):
OPENAI_API_KEY=your_api_key

Comparison: Stagehand Native vs Puppeteer

FeatureStagehand NativeWith Puppeteer
SetupSimple - use stagehand.context.pages()Requires puppeteer.connect()
Page Accessstagehand.context.pages()[0]await browser.pages()
AI Methodsstagehand.act("click")stagehand.act("click", { page: ppPage })
Best ForPure Stagehand workflowsExisting Puppeteer codebases

Next Steps

Agent

Automate entire workflows

Act

Execute actions on web pages

Extract

Extract structured data from pages

Observe

Observe and find elements on pages