> ## Documentation Index
> Fetch the complete documentation index at: https://tbd-6fc993ce-hypeship-gb-hour-pricing-clarity.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Stagehand

[Stagehand](https://github.com/browserbase/stagehand) is an open source AI browser automation framework. It lets developers choose what to write in code vs. natural language. By integrating with Kernel, you can run Stagehand automations with cloud-hosted browsers.

<Note>
  This guide covers both Stagehand SDK v4 and v3. v4 runs as a Chrome extension alongside the browser rather than driving it purely over CDP, so a remote Kernel browser needs the extension loaded into it — the version tabs below show each setup. To move between versions, see the [Stagehand migration guide](https://docs.stagehand.dev). The CLI template uses v4.
</Note>

## Quick start with the Stagehand template

The fastest way to run Stagehand on Kernel is our app template, which comes pre-wired for v4:

```bash theme={null}
kernel create --name my-stagehand-app --language typescript --template stagehand
```

This scaffolds a self-contained app with two files:

* `index.ts` — the automation (searches a startup on Y Combinator and extracts its team size).
* `stagehand-extension.ts` — a helper that loads the Stagehand extension onto the Kernel browser.

Set a provider-prefixed `MODEL` and its API key in a `.env` file:

```bash .env theme={null}
# MODEL is provider-prefixed, e.g. anthropic/claude-sonnet-4-5, openai/gpt-4.1, google/gemini-2.5-flash
MODEL=anthropic/claude-sonnet-4-5
MODEL_API_KEY=your-api-key
```

Then deploy and invoke:

```bash theme={null}
kernel deploy index.ts --env-file .env
kernel invoke ts-stagehand teamsize-task --payload '{"company": "kernel"}'
# → {"teamSize":"6"}
```

See the [deploy](/apps/deploy) and [invoke](/apps/invoke) guides for more.

## Adding Kernel to an existing Stagehand project

If you already have a Stagehand implementation, switch it to Kernel's cloud browsers by updating your browser setup. The steps differ between v4 and v3 — pick your version below.

<Tabs>
  <Tab title="Stagehand v4">
    **1. Install the Kernel SDK**

    ```bash theme={null}
    npm install @onkernel/sdk
    ```

    **2. Load the Stagehand extension onto the Kernel browser**

    Stagehand v4 runs as a Chrome extension. When `localBrowser.connect` is called without an `extensionId`, Stagehand loads the extension into the running browser over CDP (`Extensions.loadUnpacked`), reading it from a path on the **browser's** filesystem. Mirror the extension — shipped inside the `@browserbasehq/stagehand` package — onto the running Kernel browser at that exact path first:

    ```typescript theme={null}
    import { Kernel } from "@onkernel/sdk";
    import { createReadStream } from "node:fs";
    import { dirname, join } from "node:path";
    import { fileURLToPath } from "node:url";

    const stagehandDist = dirname(fileURLToPath(import.meta.resolve("@browserbasehq/stagehand")));
    const STAGEHAND_EXTENSION_ZIP = join(stagehandDist, "assets/stagehand-extension.zip");
    const STAGEHAND_EXTENSION_DIR = join(stagehandDist, "extension");

    async function loadStagehandExtension(kernel: Kernel, sessionId: string): Promise<void> {
      await kernel.browsers.fs.uploadZip(sessionId, {
        dest_path: STAGEHAND_EXTENSION_DIR,
        zip_file: createReadStream(STAGEHAND_EXTENSION_ZIP),
      });
    }
    ```

    **3. Create a browser and connect**

    Create a Kernel browser, load the extension, then connect Stagehand to its CDP URL:

    ```typescript theme={null}
    import { Stagehand, localBrowser } from "@browserbasehq/stagehand";
    import Kernel from "@onkernel/sdk";

    const kernel = new Kernel();

    const kernelBrowser = await kernel.browsers.create({ stealth: true });
    console.log("Live view url:", kernelBrowser.browser_live_view_url);

    await loadStagehandExtension(kernel, kernelBrowser.session_id);

    // With no `extensionId`, Stagehand loads the extension over CDP.
    const browser = await localBrowser.connect({ cdpUrl: kernelBrowser.cdp_ws_url });

    const stagehand = await Stagehand.create({
      browser,
      model: {
        modelName: "anthropic/claude-sonnet-4-5",
        apiKey: process.env.MODEL_API_KEY,
      },
    });
    ```

    **4. Use your Stagehand automation**

    Drive the page with Stagehand's primitives. Note the v4 API: page access is async (`activePage()`), and `extract` returns its result under `data`:

    ```typescript theme={null}
    import { z } from "zod";

    const page = await browser.context.activePage();
    if (!page) throw new Error("No active page in the Kernel browser");
    await page.goto("https://www.ycombinator.com/companies");

    await stagehand.act("Type in kernel into the search box");
    await stagehand.act("Click on the first search result");

    const { data } = await stagehand.extract(
      "Extract the team size (number of employees) shown on this Y Combinator company page.",
      z.object({ teamSize: z.string() }),
    );

    console.log("Team size:", data.teamSize);
    ```

    **5. Clean up**

    Stagehand v4 only closes browsers it launched, so close the connection and delete the Kernel browser yourself. Nest the cleanup so a failed `close()` never skips deleting the browser:

    ```typescript theme={null}
    try {
      await stagehand.close();
    } finally {
      try {
        await browser.close();
      } finally {
        await kernel.browsers.deleteByID(kernelBrowser.session_id);
      }
    }
    ```
  </Tab>

  <Tab title="Stagehand v3">
    **1. Install the Kernel SDK**

    ```bash theme={null}
    npm install @onkernel/sdk
    ```

    **2. Initialize Kernel and create a browser**

    Import the libraries and create a cloud browser session:

    ```typescript theme={null}
    import { Stagehand } from "@browserbasehq/stagehand";
    import Kernel from "@onkernel/sdk";
    import { z } from "zod";

    const kernel = new Kernel();

    const kernelBrowser = await kernel.browsers.create({ stealth: true });

    console.log("Live view url: ", kernelBrowser.browser_live_view_url);
    ```

    **3. Update your browser configuration**

    Replace your existing browser setup to use Kernel's CDP URL:

    ```typescript theme={null}
    const stagehand = new Stagehand({
      env: "LOCAL",
      localBrowserLaunchOptions: {
        cdpUrl: kernelBrowser.cdp_ws_url,
      },
      model: "openai/gpt-4.1",
      apiKey: process.env.OPENAI_API_KEY,
      verbose: 1,
      domSettleTimeout: 30_000
    });

    await stagehand.init();
    ```

    **4. Use your Stagehand automation**

    Use Stagehand's page methods with the Kernel-powered browser:

    ```typescript theme={null}
    const page = stagehand.context.pages()[0];
    await page.goto("https://onkernel.com");
    await stagehand.act("Click on Blog in the navbar");
    await stagehand.act("Click on the newest blog post");
    const output = await stagehand.extract(
      "Extract a summary of the blog post",
      z.object({ summary: z.string() })
    );

    console.log("Newest blog post summary: ", output.summary);

    // Clean up
    await stagehand.close();
    await kernel.browsers.deleteByID(kernelBrowser.session_id);
    ```
  </Tab>
</Tabs>

## Benefits of using Kernel with Stagehand

* **No local browser management**: Run automations without installing or maintaining browsers locally
* **Scalability**: Launch multiple browser sessions in parallel
* **Stealth mode**: Built-in anti-detection features for web scraping
* **Session state**: Maintain browser state across runs via [Profiles](/auth/profiles)
* **Live view**: Debug your automations with real-time browser viewing

## Next steps

* Check out [live view](/browsers/live-view) for debugging your automations
* Learn about [stealth mode](/browsers/bot-detection/stealth) for avoiding detection
* Learn how to properly [terminate browser sessions](/browsers/termination)
* Learn how to [deploy](/apps/deploy) your Stagehand app to Kernel
