Migrate from Browserbase
Already written against the Browserbase SDK? Change the import and the key. Sessions, contexts, live view and recording work the same way, and anything Solari can't do raises a clear error instead of silently doing something different.
Install
npm install @solarisdk/browserbase-compat
pip install solari-browserbase-compatUse it
import Browserbase from "@solarisdk/browserbase-compat"
import { chromium } from "playwright-core"
const bb = new Browserbase({ apiKey: process.env.SOLARI_API_KEY }) // slr_… key
const session = await bb.sessions.create()
const browser = await chromium.connectOverCDP(session.connectUrl)
const page = browser.contexts()[0].pages()[0] ?? (await browser.contexts()[0].newPage())
await page.goto("https://example.com")
await browser.close()
await bb.sessions.update(session.id, { status: "REQUEST_RELEASE" })import os
from solari_browserbase import Browserbase
from playwright.sync_api import sync_playwright
bb = Browserbase(api_key=os.environ["SOLARI_API_KEY"]) # slr_… key
session = bb.sessions.create()
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(session.connect_url)
page = browser.contexts[0].pages[0] if browser.contexts[0].pages else browser.contexts[0].new_page()
page.goto("https://example.com")
browser.close()
bb.sessions.update(session.id, status="REQUEST_RELEASE")connectUrl is a plain Chrome DevTools Protocol URL, so Playwright, Puppeteer, Stagehand and browser-use all connect, and there is no client version to pin. Keep the URL private: the session id inside it is the credential.
slr_ are used. A Browserbase key in BROWSERBASE_API_KEY is skipped, never sent anywhere, and never printed.What works
| Browserbase | On Solari |
|---|---|
sessions.create / retrieve / list / update | Yes. REQUEST_RELEASE releases the session; statuses map to RUNNING, COMPLETED, TIMED_OUT, ERROR. |
connectUrl | A raw CDP websocket URL. |
proxies: true, geolocation | A managed proxy in the country, state or city you pick. It runs on the stealth browser, which is switched on for you. |
verified, advancedStealth | The stealth browser. |
solveCaptchas: true | Captcha solving. Off unless you pass true (Browserbase turns it on by default). |
recordSession: true | Session recording, off unless you pass true. Read it back with sessions.recording.retrieve. |
allowedDomains | Egress allowlist (enterprise plan). |
| Contexts | Saved as Solari profiles: cookies and localStorage. |
sessions.debug | A view-only live-view link. |
What is different
- Recording is a DOM-event log, not video.
sessions.recording.retrievereturns the events a few seconds after you release the session. There is no HLS or MP4. - Contexts keep cookies and localStorage, not IndexedDB or service workers.
- Timeout, keepAlive and metadata work as in Browserbase (package version 0.2.0 and later).
timeoutis in seconds, at least 60, and is capped at your plan's maximum session length. WithoutkeepAlive, a session whose connection drops is released about 45 seconds later.keepAlive: truekeeps it after your client disconnects, until itstimeout(one hour if you set none), the plan maximum, or a release.userMetadata(up to 50 keys, 8 KB) comes back fromretrieveandlistand can be filtered withsessions.list({ q: "user_metadata['run']:'nightly'" }). - Viewport is a known gap. Setting the viewport at create has no effect; call
page.setViewportSizefrom your automation client. - No effect, with a warning:
viewport,blockAds,logSessionandos. Passstrict: trueto make them errors.
Contexts
const ctx = await bb.contexts.create({ name: "shop-login" })
const s = await bb.sessions.create({
browserSettings: { context: { id: ctx.id, persist: true } },
})
// …log in, then release through the same client to save it:
await bb.sessions.update(s.id, { status: "REQUEST_RELEASE" })
// Next time, the saved login comes back as storageState:
const s2 = await bb.sessions.create({ browserSettings: { context: { id: ctx.id } } })
const browser = await chromium.connectOverCDP(s2.connectUrl)
const page = await (await browser.newContext({ storageState: s2.storageState })).newPage()The saved cookies are also present in the browser's default context, so browser.contexts()[0] should already be signed in. localStorage is not applied there: create a browser context with the state, with newContext({ storageState }), to get both.
Not supported
These raise SolariCompatUnsupported: browser extensions, the Selenium endpoint, the downloads and uploads APIs, video replays, session logs, bring-your-own proxies, per-domain proxy rules, custom CA certificates, ignoreCertificateErrors, custom captcha selectors, mobile and tablet profiles, regions other than us-west-2, and the separate Projects, Agents, Fetch and Search products.
The full list, with every difference, is in each package's COMPAT.md.
