A stealth browser for Playwright & Puppeteer
Clearcote is Chromium, so the automation you already have keeps working. Swap the launch call for the SDK's launch() and you get back a standard Playwright Browser, running a build whose identity controls are compiled into the engine instead of injected as JavaScript.
The open build needs no account. The latest build is free with GitHub for one browser at a time.
Change the launch line, keep everything else
# pip install clearcote
from clearcote import launch
browser = launch(fingerprint="account-42", light_stealth=True)
page = browser.new_page()
page.goto("https://example.com")
browser.close()Highlights
A one-line migration
launch() and launchPersistentContext() return standard Playwright objects, so selectors, fixtures and page objects stay as they are. Puppeteer uses the same binary through executablePath.
A verified binary, fetched for you
On first use the SDK downloads the matching build and checks its SHA-256 against values baked into the SDK. Opt-in auto-update also verifies the signed release manifest.
Identity as named options
fingerprint, platform, brand, timezone, acceptLanguage, proxy and geoip are arguments, not switches to remember. One seed keeps an identity stable across runs.
Coherent defaults
Headed launches skip the emulated viewport so the page size matches the real window, WebRTC keeps your machine's address private, and Privacy Sandbox APIs are off.
Humanized input, one flag
humanize: true sends clicks, typing, drags and scrolls as trusted native input on curved paths, with navigator.webdriver left false.
Three languages
Python (sync and async), Node and .NET, on PyPI, npm and NuGet. The higher-level helpers (humanize, geoip, saved profiles) are Python and Node for now.
What the SDK does for you
The package wraps the Clearcote binary so identity options become named arguments. It resolves the browser in a fixed order (an explicit path, the CLEARCOTE_BINARY environment variable, then its verified cache), launches it through Playwright, and hands back the objects your code already uses.
Because the controls live in the C++ engine, there's no stealth plugin to load and nothing injected into the page. A plugin patches properties from JavaScript, and a patched getter can be told apart from a native one. Here the getter is the native one, in the main frame, in iframes and in workers. How detection works explains why that matters.
Two things behave differently from stock Chromium, both on purpose. Console and page-error events aren't forwarded to the automation client, because forwarding them is what an automation probe measures; collect them in the page and read them back with page.evaluate(). And a SOCKS5 proxy with a username and password works directly, because the engine implements the authentication stock Chromium lacks.
A stealth plugin next to an engine-level browser
Open-source stealth plugins are a reasonable first step, and many projects start there. See the comparison with puppeteer-extra-plugin-stealth for a fuller picture.
What people use it for
Scraping and data collection
Keep your existing Playwright or Puppeteer crawler and change what's underneath it.
End-to-end tests on real pages
Test flows on sites that treat stock automated Chromium differently from a normal browser.
Migrating an existing suite
Selectors, fixtures and page objects stay put; only the launch call changes.
Fingerprinting research
Run the same scripts with and without a persona and compare what a page measures.
Clearcote is built for privacy, testing, research and lawful automation. You're responsible for how you use it and for following the terms of the sites you visit.
Which plan includes it
The SDK and every identity option are in all three tiers. Without a key it runs the open build. With a licence key (free with a GitHub account) it runs the latest build, with the licensed-only extras on the pricing page.
Compare plansFAQ
Is it really a drop-in replacement?
For Playwright, yes: launch() and launchPersistentContext() return the standard objects, so everything after the launch line is unchanged. Puppeteer uses the same binary through executablePath, and the .NET SDK returns a standard Microsoft.Playwright IBrowser.
Do I still need puppeteer-extra-plugin-stealth or playwright-stealth?
No, and it's better not to add one. Those plugins patch values from injected JavaScript, and the patching can itself be noticed. Clearcote sets the values in the engine, so there's nothing left for a plugin to patch.
Does it work headless?
Yes. Headed is still the safer default where you can run it, because headless mode has tells of its own. In containers, the official Docker image runs headed under a virtual display by default.
Which languages are supported?
Python (sync and async APIs), Node.js and .NET. Python and Node also include the higher-level helpers: humanized input, geoip matching, saved profiles, render-coherence checks and the in-browser agent.
How do I keep the same identity between runs?
Reuse the same fingerprint seed, and use launchPersistentContext with a user-data directory so cookies and storage persist. Deriving the seed from your own account or tenant id keeps it reproducible. See persistent identities.
Go deeper in the docs
Related features
One option turns Playwright's clicks, typing, drags and scrolls into trusted native input on curved paths, with human timing.
Canvas, WebGL, WebGPU, audio, fonts, screen, hardware and locale set in the C++ engine from one seed, so every surface agrees with every other.
Set a proxy with geoip on and the timezone, languages and WebRTC follow the exit IP. SOCKS5 with a username and password works directly.
Run Clearcote as a standing CDP endpoint from the official Docker image, serve() or a CLI, and attach any framework with no code change.
Related reading
Try Clearcote
Open source, a drop-in for Playwright & Puppeteer, and coherent down to the TLS handshake.
Free for one browser with GitHub. No card.