> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stagehand.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate TypeScript v2 to v3

> Complete migration guide from Stagehand TypeScript SDK v2 to v3

export const V3Banner = () => null;

<V3Banner />

## Recommended Migration Process

1. **Backup your project**. If you use a version control system, make sure all previous versions are committed.
2. **Upgrade to Stagehand v3**.
3. Follow the breaking changes guide below.
4. Verify your project is working as expected.
5. Commit your changes.

## Stagehand v3 Package Version

Update your `package.json` to use Stagehand v3:

```bash Bash theme={null}
npm install @browserbasehq/stagehand@latest
```

## Overview of Major Changes

Stagehand v3 introduces significant improvements to the API design and functionality:

* **Removing Playwright Dependency**: Stagehand v3 is now a standalone library that does not depend on Playwright. **You can still use Stagehand with Playwright, check out our [Playwright integration](/v3/integrations/playwright) for more details.**
* **Simplified Method Signatures**: Cleaner, more intuitive parameter structures.
* **Unified Model Configuration**: Model configuration is now consolidated into a single `model` parameter.
* **Automatic iframe & Shadow DOM Support**: No more manual flags required.
* **Improved Type Safety**: Better TypeScript inference and type checking.
* **Enhanced Multi-Page Support**: New Context API for managing multiple pages.
* **Streamlined Timeouts**: Consistent timeout naming across all methods.
* **Auto-caching**: Stagehand v3 now automatically caches actions and agent steps using the [file system cache](/best-practices/caching).
* **Agent Improvements**: Renamed parameters (`instructions` → `systemPrompt`), unified model configuration, and new `executionModel` option for cost optimization.

## Breaking Changes

### Stagehand Initialization

#### Model Configuration Consolidation

The `modelName` and `modelClientOptions` parameters have been unified into a single `model` parameter.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({
  env: "BROWSERBASE",
  apiKey: process.env.BROWSERBASE_API_KEY,
  modelName: "openai/gpt-5",
  modelClientOptions: {
    apiKey: process.env.OPENAI_API_KEY
    baseURL: "https://custom-proxy.com/v1"
  }
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { Stagehand } from "@browserbasehq/stagehand";

// Option 1: String format (recommended for simplicity, auto-loads model API key from env)
const stagehand = new Stagehand({
  env: "BROWSERBASE",
  apiKey: process.env.BROWSERBASE_API_KEY,
  model: "openai/gpt-5"
});

// Option 2: Object format (for advanced configuration)
const stagehand = new Stagehand({
  env: "BROWSERBASE",
  apiKey: process.env.BROWSERBASE_API_KEY,
  model: {
    modelName: "gpt-5",
    apiKey: process.env.OPENAI_API_KEY,
    baseURL: "https://custom-proxy.com/v1"
  }
});
```

#### DOM Settle Timeout Rename

The `domSettleTimeoutMs` parameter has been renamed to `domSettleTimeout` for consistency.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({
  env: "LOCAL",
  domSettleTimeoutMs: 5000
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({
  env: "LOCAL",
  domSettleTimeout: 5000
});
```

#### Changes to return value of `stagehand.init()`

The `init()` used to return `debugUrl`, `sessionUrl` and `sessionId`

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const result = await stagehand.init();
console.log(result);
```

In `v2`, the returned object contains:

```
{
  debugUrl: 'https://www.browserbase.com/devtools/inspector.html?wss=connect.browserbase.com/debug/f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0/devtools/page/5474B0E0510C5B6E629BEB06E799CD70?debug=true',
  sessionUrl: 'https://www.browserbase.com/sessions/f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0',
  sessionId: 'f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0'
}
```

In `v3` the return value is `Promise<void>`. The `sessionId`, `sessionUrl`, and `debugUrl` are now directly accessible via the stagehand object:

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
console.log("debugUrl: ", stagehand.browserbaseDebugURL)
console.log("sessionUrl: ", stagehand.browserbaseSessionURL)
console.log("sessionId: ", stagehand.browserbaseSessionID)
```

Example output:

```
debugUrl: 'https://www.browserbase.com/devtools/inspector.html?wss=connect.browserbase.com/debug/f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0/devtools/page/5474B0E0510C5B6E629BEB06E799CD70?debug=true',
sessionUrl: 'https://www.browserbase.com/sessions/f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0',
sessionId: 'f8a21b4a-6fa1-4ab9-9007-fbfe61dc14f0'
```

#### Caching Changes

The `enableCaching` boolean has been replaced with a `cacheDir` string for more flexible cache management.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({
  env: "LOCAL",
  enableCaching: true
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({
  env: "LOCAL",
  cacheDir: "./stagehand-cache"  // Specify cache directory
});
```

#### Page Access Changes

Direct page access has changed to use the Context API.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();

// Direct page access
const page = stagehand.page;
await page.goto("https://example.com");
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();

// Access via context
const page = stagehand.context.pages()[0];
await page.goto("https://example.com");

// Or `await` the active page
const page = stagehand.context.awaitActivePage();
await page.goto("https://example.com");
```

### Context and Multi-Page Management

#### New Context API

v3 introduces a structured Context API for managing multiple pages.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();

// Limited multi-page support
const page = stagehand.page;
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();

// Access all pages
const pages = stagehand.context.pages();
const mainPage = pages[0];

// Create new page
const newPage = await stagehand.context.newPage();

// Set active page
stagehand.context.setActivePage(newPage);

// implicitly takes action on newPage
await stagehand.act("click button");
```

### act() Method Changes

#### Method Signature Simplification

The `action` parameter has been removed from `ActOptions`. Now you only pass the instruction as a string.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
await page.act({
  action: "click the login button",
  modelName: "openai/gpt-5-mini",
  variables: { username: "john" },
  timeoutMs: 10000,
  domSettleTimeoutMs: 5000,
  iframes: true
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// Clean, simple string instruction
await stagehand.act("click the login button");

// With options
await stagehand.act("click the login button", {
  model: "openai/gpt-5-mini",
  variables: { username: "john" },
  timeout: 10000,
  page: page  // Optional: specify which page
});
```

<Note>
  **Method Location Change**: In v3, `act()` is called on the `stagehand` instance, not the `page` object.
</Note>

#### Model Configuration in act()

Model configuration follows the same pattern as initialization.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
await page.act({
  action: "fill the form",
  modelName: "anthropic/claude-sonnet-4-5",
  modelClientOptions: {
    apiKey: process.env.ANTHROPIC_API_KEY
  }
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// String format
await stagehand.act("fill the form", {
  model: "anthropic/claude-sonnet-4-5"
});

// Object format
await stagehand.act("fill the form", {
  model: {
    modelName: "anthropic/claude-sonnet-4-5",
    apiKey: process.env.ANTHROPIC_API_KEY
  }
});
```

#### Timeout Parameter Rename

`timeoutMs` has been renamed to `timeout`.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
await page.act({
  action: "click button",
  timeoutMs: 15000
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
await stagehand.act("click button", {
  timeout: 15000
});
```

#### Automatic iframe Support

The `iframes` flag has been removed. iframe support is now automatic.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
await page.act({
  action: "click button inside iframe",
  iframes: true  // Required to interact with iframes
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// Automatic iframe support - no flag needed
await stagehand.act("click button inside iframe");
```

<Note>
  **Automatic Support**: Stagehand v3 automatically handles iframe and Shadow DOM interactions without requiring explicit flags.
</Note>

#### Result Structure Changes

The `ActResult` structure has been enhanced with more detailed information.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const result = await page.act("click the button");
console.log(result.action);  // Single action string
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const result = await stagehand.act("click the button");
console.log(result.actionDescription);  // Overall description
console.log(result.actions);  // Array of action details

// ActResult structure:
// {
//   success: boolean;
//   message: string;
//   actionDescription: string;
//   actions: Array<{
//     selector: string;
//     description: string;
//     method?: string;
//     arguments?: string[];
//   }>;
// }
```

### extract() Method Changes

#### Method Location and Signature

`extract()` has moved from the page object to the stagehand instance, with a cleaner parameter structure.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { z } from "zod";

const result = await page.extract({
  instruction: "extract product details",
  schema: z.object({
    name: z.string(),
    price: z.number()
  }),
  modelName: "openai/gpt-5",
  domSettleTimeoutMs: 5000,
  selector: "xpath=/html/body/div",
  iframes: true
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { z } from "zod";

// Cleaner parameter structure
const result = await stagehand.extract(
  "extract product details",
  z.object({
    name: z.string(),
    price: z.number()
  }),
  {
    model: "openai/gpt-5",
    selector: ".container", // NEW: CSS selector support
    timeout: 10000,
    page: page  // Optional: specify which page
  }
);
```

<Note>
  **Parameter Order**: In v3, `instruction` and `schema` are separate positional parameters, with `options` as an optional third parameter.
</Note>

#### Extract Without Schema

Schema-less extraction also has a simpler interface.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// String instruction
const result = await page.extract("get the page title");
// Returns: { extraction: "Page Title" }

// Raw page content
const content = await page.extract();
// Returns: { page_text: "..." }
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// String instruction
const result = await stagehand.extract("get the page title");
// Returns: { extraction: "Page Title" }

// Raw page content
const content = await stagehand.extract();
// Returns: { pageText: "..." }
```

#### Model Configuration in extract()

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const data = await page.extract({
  instruction: "extract data",
  schema: DataSchema,
  modelName: "anthropic/claude-sonnet-4-5",
  modelClientOptions: {
    apiKey: process.env.ANTHROPIC_API_KEY
  }
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const data = await stagehand.extract(
  "extract data",
  DataSchema,
  {
    model: "anthropic/claude-sonnet-4-5"
  }
);
```

#### Automatic iframe Support

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const data = await page.extract({
  instruction: "extract data from iframe",
  schema: DataSchema,
  iframes: true  // Required for iframe content
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// Automatic iframe support
const data = await stagehand.extract(
  "extract data from iframe",
  DataSchema
);
```

#### Array Schema Changes

Array extraction now has a more ergonomic syntax.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { z } from "zod";

// Had to wrap array in object
const ApartmentListingsSchema = z.object({
  apartments: z.array(z.object({
    address: z.string(),
    price: z.string(),
    bedrooms: z.number()
  }))
});

const result = await page.extract({
  instruction: "extract all apartment listings",
  schema: ApartmentListingsSchema
});

// Access via: result.apartments
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
import { z } from "zod";

// Can use array schema directly
const ApartmentListingsSchema = z.array(
  z.object({
    address: z.string(),
    price: z.string(),
    bedrooms: z.number()
  })
);

const result = await stagehand.extract(
  "extract all apartment listings",
  ApartmentListingsSchema
);

// Result is directly the array
console.log(result[0].address);
```

### observe() Method Changes

#### Method Signature Updates

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const results = await page.observe({
  instruction: "find all buttons",
  modelName: "openai/gpt-5",
  domSettleTimeoutMs: 5000,
  drawOverlay: true,
  iframes: true
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const results = await stagehand.observe("find all buttons", {
  model: "openai/gpt-5",
  timeout: 10000,
  selector: ".container",  // NEW: scope observation to selector
  page: page  // Optional: specify which page
});
```

<Note>
  **Method Location Change**: Like `act()` and `extract()`, `observe()` is now called on the `stagehand` instance.
</Note>

#### Draw Overlay Removed

The `drawOverlay` option has been removed in v3.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const results = await page.observe({
  instruction: "find buttons",
  drawOverlay: true  // Visual debugging
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// drawOverlay is no longer available
const results = await stagehand.observe("find buttons");
```

#### Automatic iframe Support

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const results = await page.observe({
  instruction: "find elements in iframe",
  iframes: true
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// Automatic iframe support
const results = await stagehand.observe("find elements in iframe");
```

#### Observe with act() Integration

The observe → act workflow remains similar but with updated method signatures.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const [action] = await page.observe("find the login button");
await page.act(action);
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const [action] = await stagehand.observe("find the login button");
await stagehand.act(action);
```

### agent() Method Changes

#### Agent Configuration Updates

The agent configuration has been significantly restructured in v3 with renamed parameters and new capabilities.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const agent = stagehand.agent({
  provider: "google",
  model: "gemini-2.5-computer-use-preview-10-2025",
  instructions: "You are a helpful assistant that can navigate websites.",
  options: {
    apiKey: process.env.GEMINI_API_KEY
  },
  integrations: ["https://mcp-server.example.com"],
  tools: customTools
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const agent = stagehand.agent({
  model: "google/gemini-2.5-computer-use-preview-10-2025",  // Provider now in model string
  systemPrompt: "You are a helpful assistant that can navigate websites.",  // Renamed from 'instructions'
  mode: "cua",  // Computer Use Agent mode
  integrations: ["https://mcp-server.example.com"],
  tools: customTools
});
```

<Note>
  **Key Changes**:

  * `provider` removed - now part of the model string (e.g., `"anthropic/claude-sonnet-4-5"`)
  * `instructions` renamed to `systemPrompt`
  * `options` removed - use model object format for advanced configuration
  * `executionModel` added - specify a different model for tool execution
  * `cua` flag added - enable/disable Computer Use Agent mode
</Note>

#### Model Configuration in agent()

Model configuration follows the same unified pattern as other methods.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const agent = stagehand.agent({
  provider: "google",
  model: "gemini-2.5-computer-use-preview-10-2025",
  options: {
    apiKey: process.env.GEMINI_API_KEY,
    baseURL: "https://custom-proxy.com/v1"
  }
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
// String format (recommended)
const agent = stagehand.agent({
  model: "google/gemini-2.5-computer-use-preview-10-2025"
});

// Object format for advanced configuration
const agent = stagehand.agent({
  model: {
    modelName: "gemini-2.5-computer-use-preview-10-2025",
    apiKey: process.env.GEMINI_API_KEY,
    baseURL: "https://custom-proxy.com/v1"
  }
});
```

#### Execute Method Changes

The `execute()` method has been simplified with some options removed and new ones added.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const result = await agent.execute({
  instruction: "Search for products",
  maxSteps: 20,
  autoScreenshot: true,
  waitBetweenActions: 1000,
  context: "Focus on electronics category"
});
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const result = await agent.execute({
  instruction: "Search for products",
  maxSteps: 20,
  page: page,  // NEW: specify which page to operate on
  highlightCursor: true  // NEW: visual cursor for debugging
});
```

<Warning>
  **Removed Options**:

  * `autoScreenshot` - no longer available
  * `waitBetweenActions` - no longer available
  * `context` - use the `systemPrompt` in agent config instead
</Warning>

#### Execution Model Configuration

v3 introduces a new `executionModel` option to use a different (often faster/cheaper) model for tool execution.

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const agent = stagehand.agent({
  model: "anthropic/claude-sonnet-4-5",  // Main reasoning model
  executionModel: "anthropic/claude-haiku-4-5"  // Faster model for tool execution (act, extract, observe)
});

// The agent will use claude-sonnet-4-5 for high-level reasoning
// but claude-haiku-4-5 for executing individual actions
const result = await agent.execute("Complete the checkout process");
```

#### Agent with Multi-Page Support

v3 agents can now specify which page to operate on.

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const page1 = stagehand.context.pages()[0]
const page2 = await stagehand.context.newPage();

const agent = stagehand.agent({
  model: "google/gemini-2.5-computer-use-preview-10-2025"
});

// Execute on specific page
await page2.goto("https://example.com/dashboard");
const result = await agent.execute({
  instruction: "Export the data table",
  page: page2  // Operate on page2 instead of default page
});
```

### History and Metrics

#### History API

History is now async and returns a promise.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const history = stagehand.history;
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const history = await stagehand.history;
```

#### Metrics API

Metrics is now async and returns a promise.

```typescript Stagehand v2 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const metrics = stagehand.metrics;
```

```typescript Stagehand v3 icon="https://mintcdn.com/stagehand/u4M3vTBXE1a-6gkD/images/typescript.svg?fit=max&auto=format&n=u4M3vTBXE1a-6gkD&q=85&s=e6a6c12fe5620d24496c73fd902d950e" theme={null}
const metrics = await stagehand.metrics;
```

## Complete Migration Example

Here's a complete example showing a full migration:

<Tabs>
  <Tab title="Stagehand v2">
    ```typescript theme={null}
    import { Stagehand } from "@browserbasehq/stagehand";
    import { z } from "zod";

    // Initialize
    const stagehand = new Stagehand({
      env: "BROWSERBASE",
      apiKey: process.env.BROWSERBASE_API_KEY,
      modelName: "openai/gpt-5",
      modelClientOptions: {
        apiKey: process.env.OPENAI_API_KEY
      },
      enableCaching: true,
      domSettleTimeoutMs: 5000
    });

    await stagehand.init();
    const page = stagehand.page;

    // Navigate
    await page.goto("https://example.com");

    // Act
    await page.act({
      action: "click the login button",
      timeoutMs: 10000,
      iframes: true
    });

    // Extract
    const ProductSchema = z.object({
      name: z.string(),
      price: z.number(),
      inStock: z.boolean()
    });

    const product = await page.extract({
      instruction: "extract product details",
      schema: ProductSchema,
      domSettleTimeoutMs: 5000,
      iframes: true
    });

    // Observe
    const actions = await page.observe({
      instruction: "find all buttons",
      drawOverlay: false,
      iframes: true
    });

    await stagehand.close();
    ```
  </Tab>

  <Tab title="Stagehand v3">
    ```typescript theme={null}
    import { Stagehand } from "@browserbasehq/stagehand";
    import { z } from "zod";

    // Initialize - simplified configuration
    const stagehand = new Stagehand({
      env: "BROWSERBASE",
      apiKey: process.env.BROWSERBASE_API_KEY,
      model: "openai/gpt-5",  // Unified model configuration
      cacheDir: "./cache",      // Flexible cache directory
      domSettleTimeout: 5000    // Consistent naming
    });

    await stagehand.init();
    const page = stagehand.context.pages()[0];  // Context API

    // Navigate
    await page.goto("https://example.com");

    // Act - cleaner interface, automatic iframe support
    await stagehand.act("click the login button", {
      timeout: 10000
      // No iframes flag needed - automatic!
    });

    // Extract - cleaner parameter order
    const ProductSchema = z.object({
      name: z.string(),
      price: z.number(),
      inStock: z.boolean()
    });

    const product = await stagehand.extract(
      "extract product details",
      ProductSchema
      // Automatic iframe support, no extra flags needed
    );

    // Observe - simplified
    const actions = await stagehand.observe("find all buttons");
    // Automatic iframe support

    // Get metrics
    const metrics = await stagehand.metrics;
    console.log('Total tokens used:',
      metrics.totalPromptTokens + metrics.totalCompletionTokens);

    await stagehand.close();
    ```
  </Tab>
</Tabs>

## Quick Reference: Breaking Changes

<Expandable title="Stagehand Initialization">
  | Feature          | Stagehand v2                       | Stagehand v3                                                  |
  | ---------------- | ---------------------------------- | ------------------------------------------------------------- |
  | **Model Config** | `modelName` + `modelClientOptions` | `model: "provider/model"` or `{ modelName, apiKey, baseURL }` |
  | **DOM Settle**   | `domSettleTimeoutMs`               | `domSettleTimeout`                                            |
  | **Caching**      | `enableCaching: boolean`           | `cacheDir: string`                                            |
  | **Page Access**  | `stagehand.page`                   | `stagehand.context.pages()[0]`                                |
</Expandable>

<Expandable title="act()">
  | Feature              | Stagehand v2             | Stagehand v3                       |
  | -------------------- | ------------------------ | ---------------------------------- |
  | **Method location**  | `page.act()`             | `stagehand.act()`                  |
  | **Parameters**       | `{ action, ...options }` | `(instruction, options?)`          |
  | **Timeout**          | `timeoutMs`              | `timeout`                          |
  | **Result structure** | `{ action }`             | `{ actionDescription, actions[] }` |
</Expandable>

<Expandable title="extract()">
  | Feature             | Stagehand v2                          | Stagehand v3                      |
  | ------------------- | ------------------------------------- | --------------------------------- |
  | **Method location** | `page.extract()`                      | `stagehand.extract()`             |
  | **Parameters**      | `{ instruction, schema, ...options }` | `(instruction, schema, options?)` |
</Expandable>

<Expandable title="observe()">
  | Feature             | Stagehand v2           | Stagehand v3          |
  | ------------------- | ---------------------- | --------------------- |
  | **Method location** | `page.observe()`       | `stagehand.observe()` |
  | **Draw overlay**    | `drawOverlay: boolean` | Removed               |
</Expandable>

<Expandable title="agent()">
  | Feature            | Stagehand v2                                      | Stagehand v3                             |
  | ------------------ | ------------------------------------------------- | ---------------------------------------- |
  | **Provider**       | `provider: "openai" \| "anthropic"`               | Part of model string                     |
  | **Instructions**   | `instructions: string`                            | `systemPrompt: string`                   |
  | **Model**          | `model: "model-name"`                             | `model: "provider/model-name"`           |
  | **Options**        | `options: Record<string, unknown>`                | Use model object format                  |
  | **Execute params** | `autoScreenshot`, `waitBetweenActions`, `context` | Removed; added `page`, `highlightCursor` |
</Expandable>

<Expandable title="Automatic Features">
  | Feature            | Stagehand v2                  | Stagehand v3               |
  | ------------------ | ----------------------------- | -------------------------- |
  | **iframe support** | `iframes: true` flag required | Automatic (no flag needed) |
  | **Shadow DOM**     | Manual handling               | Automatic (no flag needed) |
</Expandable>

<Expandable title="Properties & Methods">
  | Feature     | Stagehand v2        | Stagehand v3              |
  | ----------- | ------------------- | ------------------------- |
  | **History** | `stagehand.history` | `await stagehand.history` |
  | **Metrics** | `stagehand.metrics` | `await stagehand.metrics` |
</Expandable>

## Troubleshooting

### Error: Cannot find property 'page' on Stagehand instance

**Problem**: Direct `stagehand.page` is not supported in Stagehand v3.

**Solution**: Use the Context API or `await` the active page:

```typescript theme={null}
// Use context API (recommended)
const page = stagehand.context.pages()[0];

// Or grab the active page
const page = await stagehand.context.awaitActivePage();
```

### Error: act() method not found on page

**Problem**: v3 moved `act()`, `extract()`, and `observe()` to the stagehand instance.

**Solution**: Call these methods on the stagehand instance:

```typescript theme={null}
// v2 ❌
await page.act("click button");

// v3 ✅
await stagehand.act("click button");
```

### TypeScript: Model configuration type errors

**Problem**: TypeScript errors with model configuration.

**Solution**: Use the proper format:

```typescript theme={null}
// String format
model: "openai/gpt-5"

// Object format
model: {
  modelName: "openai/gpt-5",
  apiKey: process.env.OPENAI_API_KEY
}
```

### Agent configuration errors

**Problem**: Using old `provider` and `instructions` parameters.

**Solution**: Update to v3 format:

```typescript theme={null}
// v2 ❌
const agent = stagehand.agent({
  provider: "anthropic",
  model: "claude-sonnet-4-5",
  instructions: "You are a helpful assistant that..."
});

// v3 ✅
const agent = stagehand.agent({
  model: "anthropic/claude-sonnet-4-5",
  systemPrompt: "You are a helpful assistant that..."
});
```

### Agent execute options not recognized

**Problem**: Using removed options like `autoScreenshot`, `waitBetweenActions`, or `context`.

**Solution**: Remove these options and use v3 alternatives:

```typescript theme={null}
// v2 ❌
await agent.execute({
  instruction: "task",
  autoScreenshot: true,
  waitBetweenActions: 1000,
  context: "additional context"
});

// v3 ✅
const agent = stagehand.agent({
  model: "google/gemini-2.5-computer-use-preview-10-2025",
  systemPrompt: "Your context here."  // Move context to systemPrompt
});

await agent.execute({
  instruction: "task",
  highlightCursor: true  // Use new option for visual feedback
});
```

## Best Practices for v3

1. **Use the string model format** for simplicity: `model: "openai/gpt-5"`
2. **Leverage automatic iframe support** - remove all `iframes` flags
3. **Use the Context API** for multi-page scenarios
4. **Monitor metrics** to track token usage and optimize costs
5. **Use history** for debugging and understanding automation flow
6. **Set appropriate timeouts** based on your use case
7. **Specify cache directory** to improve performance for repeated actions
8. **Use executionModel for agents** - configure a faster/cheaper model for tool execution while keeping a powerful model for reasoning (e.g., `model: "anthropic/claude-sonnet-4-5"`, `executionModel: "google/gemini-2.0-flash"`)

## Additional Resources

* [Stagehand v3 Documentation](/v3/first-steps/introduction)
* [API Reference](/v3/references/stagehand)
* [Best Practices](/v3/best-practices/caching)
* [GitHub Issues](https://github.com/browserbase/stagehand/issues)

If you encounter any issues during migration, please [open an issue](https://github.com/browserbase/stagehand/issues) on our GitHub repository.
