Skip to content

Switching to Clearcote

Clearcote is a real Chromium that speaks CDP, so existing code usually moves over by changing the lines that start or find the browser. The code after them stays the same.

From Playwright

launch() returns the same Playwright Browser, so only the launch call changes. With playwright-stealth or Patchright, the plugin goes too.

from playwright.sync_api import sync_playwright
browser = sync_playwright().start().chromium.launch()
from clearcote import launch
browser = launch(fingerprint="acct-1")
page = browser.new_page()

Migrating from playwright-stealth or Patchright →

From puppeteer-extra-plugin-stealth

Keep Puppeteer and drop the plugin. serve() starts Clearcote with a CDP endpoint, and Puppeteer connects to it.

import puppeteer from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch();
import puppeteer from "puppeteer-core";
import { serve } from "clearcote";
const srv = await serve({ fingerprint: "acct-1" });
const browser = await puppeteer.connect({ browserURL: srv.cdpUrl, defaultViewport: null });
const page = await browser.newPage();

Migrating from puppeteer-extra-plugin-stealth →

From undetected-chromedriver

This is the one move that is more than a line: Clearcote is driven over CDP, not WebDriver, so the script moves to Playwright. Most Selenium calls have a one-line counterpart. The same goes for selenium-stealth.

import undetected_chromedriver as uc
driver = uc.Chrome(headless=True)
driver.get("https://example.com")
from clearcote import launch
browser = launch(fingerprint="acct-1")
page = browser.new_page()
page.goto("https://example.com")

Migrating from undetected-chromedriver →

From Camoufox

Both hand you a Playwright object from a patched engine, so Camoufox(...) becomes launch(...), mostly with the same option names, on Chromium.

from camoufox.sync_api import Camoufox
with Camoufox(os="windows", humanize=True) as browser:
    page = browser.new_page()
from clearcote import launch
browser = launch(platform="windows", humanize=True, fingerprint="acct-1")
page = browser.new_page()

Migrating from Camoufox →

From an anti-detect browser app

Multilogin, GoLogin, AdsPower, Dolphin Anty, Kameleo: a profile becomes a seed for the device and a folder for the cookies. There is no desktop app to keep running and no local API to call first.

ws = start_profile("k1abc23")          # the app's local API hands out a CDP address
browser = sync_playwright().start().chromium.connect_over_cdp(ws)
page = browser.contexts[0].new_page()
from clearcote import launch_persistent_context
context = launch_persistent_context("profiles/acct-1", fingerprint="acct-1")
page = context.new_page()

Migrating from an anti-detect browser app →

From Fortress (BSD releases)

Your client keeps connecting to a CDP endpoint; only what starts the endpoint changes. In Docker, swap the image for teamflatearth/clearcote and keep the port.

with Fortress() as f:
    browser = p.chromium.connect_over_cdp(f.cdp_url)
with serve(fingerprint="acct-1", port=9222) as srv:
    browser = p.chromium.connect_over_cdp(srv.cdp_url)

Migrating from Fortress →

From Browserless

Your code still connects to a WebSocket address. A Clearcote session gives you one per connection, or the SDK creates the session and connects in one call.

import { chromium } from "playwright-core";
const browser = await chromium.connectOverCDP("wss://production-sfo.browserless.io?token=" + TOKEN);
import { launch } from "clearcote";
const browser = await launch({ cloud: true, identity: "acct-1", country: "us" });
const page = await browser.contexts()[0].newPage();

Migrating from Browserless →

From Browserbase

Same shape: create a session, connect to its address. sessions.create() becomes POST /api/v1/browsers, or launch(cloud=True) does both.

session = Browserbase(api_key=BROWSERBASE_API_KEY).sessions.create()
browser = sync_playwright().start().chromium.connect_over_cdp(session.connect_url)
from clearcote import launch
browser = launch(cloud=True, identity="acct-1", country="us")
page = browser.contexts[0].new_page()

Migrating from Browserbase →

What to delete along the way

Clearcote sets the fingerprint inside the engine, from one fingerprint seed. Whatever your old setup changed from the outside now works against it:

  • stealth plugins and evasion scripts (evaluateOnNewDocument, add_init_script patches of navigator);
  • a hand-set user agent, viewport, platform, WebGL vendor or GPU string;
  • timezone and language overrides when you use a proxy: pass geoip=True and they follow the exit IP.

Give each account its own seed and keep it: the same seed is the same device every time. Without a licence key the SDK runs the open build (BSD-3, no account); a free key from a GitHub sign-in gets the latest build. See Recommended settings and Installation.