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

# rebrowser

> Use a Surfsky cloud browser with rebrowser-playwright or rebrowser-puppeteer, the patched Playwright and Puppeteer.

rebrowser-playwright and rebrowser-puppeteer are Playwright and Puppeteer with [rebrowser-patches](https://github.com/rebrowser/rebrowser-patches) applied, which close the automation leaks anti-bot scripts look for in the plain libraries. The API is the same; only the package and the import change. Both connect to a Surfsky browser over the session's CDP WebSocket URL, like [Playwright](https://docs.surfsky.io/quickstart/playwright.md). [Patchright](https://docs.surfsky.io/quickstart/patchright.md) is the other maintained fork.

To have a coding agent set this up in your project, give it the [setup prompt](https://docs.surfsky.io/coding-agents.md).

> [!WARNING]
>
> Use [human-emulation commands](https://docs.surfsky.io/human_emulation.md) for clicks, typing, and scrolling.
> Keep rebrowser-playwright for navigation, selectors, waiting, and page content.

## Prerequisites

Set your [API token and base URL](https://docs.surfsky.io/quickstart.md#before-you-start). The browser runs in Surfsky's cloud, so skip the fork's browser download step. Proxy, fingerprint, and other start options are in the [API reference](https://docs.surfsky.io/api-reference/profiles/start-one-time-session.md).

## Run an example

The examples use a one-time profile. To reuse a saved login, pass a [persistent profile](https://docs.surfsky.io/sessions.md#persistent-profiles) UUID to the session call instead.

> [tab] Python
>
> Requires Python 3.12 or newer.
>
> ```bash theme={null}
> pip install surfsky rebrowser-playwright
> ```
>
> Save as `surfsky_rebrowser.py`:
>
> ```python theme={null}
> import asyncio
> from rebrowser_playwright.async_api import async_playwright
> from surfsky import AsyncSurfsky
>
>
> async def main():
>     async with (
>         AsyncSurfsky() as client,
>         client.session() as session,
>         async_playwright() as pw,
>     ):
>         browser = await pw.chromium.connect_over_cdp(session.connect_url)
>         context = browser.contexts[0]
>         page = context.pages[0] if context.pages else await context.new_page()
>         await page.goto("https://example.com")
>         print(await page.title())
>
>
> asyncio.run(main())
> ```
>
> Run it:
>
> ```bash theme={null}
> python surfsky_rebrowser.py
> ```

> [tab] TypeScript
>
> Requires Node.js 24 or newer, or Bun: both run TypeScript directly and support `await using`.
>
> ```bash theme={null}
> npm install surfsky rebrowser-playwright-core
> ```
>
> Save as `surfsky-rebrowser.mts`:
>
> ```typescript theme={null}
> import { chromium } from "rebrowser-playwright-core";
> import { Surfsky } from "surfsky";
>
> const client = new Surfsky();
> await using session = await client.session();
> const browser = await chromium.connectOverCDP(session.ws_url);
> try {
>   const context = browser.contexts()[0];
>   const page = context.pages()[0] ?? (await context.newPage());
>   await page.goto("https://example.com");
>   console.log(await page.title());
> } finally {
>   await browser.close();
> }
> ```
>
> Run it:
>
> ```bash theme={null}
> node surfsky-rebrowser.mts
> ```

Expected output:

```text theme={null}
Example Domain
```

The session scope stops the browser when it exits, including on errors. `browser.close()` over CDP only disconnects.

## rebrowser-puppeteer

For [Puppeteer](https://docs.surfsky.io/quickstart/puppeteer.md) code, the same patches ship as `rebrowser-puppeteer-core`:

```bash theme={null}
npm install surfsky rebrowser-puppeteer-core
```

Save as `surfsky-rebrowser-puppeteer.mts`:

```typescript theme={null}
import puppeteer from "rebrowser-puppeteer-core";
import { Surfsky } from "surfsky";

const client = new Surfsky();
await using session = await client.session();
const browser = await puppeteer.connect({
  browserWSEndpoint: session.ws_url,
  defaultViewport: null,
});
try {
  const page = (await browser.pages())[0] ?? (await browser.newPage());
  await page.goto("https://example.com");
  console.log(await page.title());
} finally {
  await browser.disconnect();
}
```

Run it with `node surfsky-rebrowser-puppeteer.mts`. `defaultViewport: null` keeps the window size from the profile's fingerprint.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.