Skip to content
SDK · Python · Node · .NET

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

JavaScript stealth plugin
Clearcote
Where the change lives
Script injected into every page and frame
Compiled into the Chromium engine
Native-function checks
A patched getter stringifies to its own source
The getter is native code, so it reports [native code]
Workers and iframes
Each realm has to be patched again, and gaps show
The same values everywhere, from one engine
TLS and HTTP/2
Whatever the underlying browser sends
Follows the Chrome version the persona claims
Setup
A plugin, its evasions and their options
One launch() call

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 plans

FAQ

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

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.