Plain Playwright leaks its own automation at the protocol level before a single fingerprinting script runs: the CDP call Runtime.enable, which Playwright issues on every new page to know when a JavaScript execution context is ready, is itself an observable event a detector can watch for. Patchright is a patched fork of Playwright that fixes that class of leak directly in the driver rather than trying to hide it with injected JavaScript. It's a drop-in replacement — same chromium.launch(), same page.goto() — with the Chromium-automation tells removed underneath. This guide installs it, launches it with the config its own maintainers say actually matters, and is honest about the one fingerprint check our own benchmark found it still fails.
What Runtime.enable actually leaks, and why patching the driver beats patching the page
Most stealth tooling works by injecting JavaScript after the page loads: overwrite navigator.webdriver, fake a plugin list, redefine navigator.plugins.length. The problem our Camoufox post already covers is that an injected patch is itself inspectable — a site can check whether a property descriptor looks native or looks redefined, independent of what value it returns.
Patchright takes a different approach: it patches the automation driver itself, before any page-level JavaScript runs. The specific leak it's built around is Runtime.enable, a Chrome DevTools Protocol call that Playwright sends on every new page so it knows when a JavaScript execution context has been created. Automated Chromium sessions emit this call; a real user's browser never does, which makes it a clean automation signal for anti-bot vendors to watch for over the CDP connection itself, not the page content. Patchright's fix runs Playwright's own JavaScript evaluation in isolated execution contexts instead, so the driver never has to send that call in the first place. Its second core patch does the same thing for Console.enable — disabling the Console API's CDP hooks entirely, at the cost of console.log output from the page not reaching you through Playwright anymore. A third patch adjusts Chromium's own launch flags: it adds --disable-blink-features=AutomationControlled and removes flags like --enable-automation and --disable-popup-blocking that stock Playwright sets and that a detector can read directly off the process command line.
One patch is useful beyond stealth specifically: Patchright can interact with elements inside closed shadow roots using normal locators and XPath, which stock Playwright can't reach at all. Plenty of real sites (not just anti-bot targets) use closed shadow DOM for web components, so this alone can unblock a scraper that has nothing to do with detection.
Install it
pip install patchright
patchright install chromium
patchright install chromium downloads Patchright's own patched Chromium build — it is not the same binary a stock playwright install pulls down, so skipping this step leaves you launching an unpatched browser under a patched API.
Launch it
The API is Playwright's, unchanged:
from patchright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()
An async version exists with an identical shape (from patchright.async_api import async_playwright). That bare example is enough to prove the import swap works, but it isn't the configuration Patchright's own maintainers recommend for an actual scraping target:
from patchright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch_persistent_context(
user_data_dir="./chrome-profile",
channel="chrome",
headless=False,
no_viewport=True,
)
page = browser.new_page()
page.goto("https://tls.browserleaks.com/json")
print(page.content())
browser.close()
Four choices here come straight from the project's own README, not general Playwright advice:
- launch_persistent_context, not launch — a persistent user_data_dir gives the profile cookies, cache, and local storage that accumulate over a real browsing history, which a fresh incognito-style context never has.
- channel="chrome", not the bundled Chromium — a real Google Chrome install has branding and build details a detector can check for that generic Chromium doesn't carry.
- headless=False — Patchright's stealth patches target CDP- and driver-level leaks, not headless-mode rendering differences, so the maintainers recommend running headful (or behind a virtual display like Xvfb) rather than relying on headless mode to also stay undetected.
- No custom headers or user_agent — overriding either without also rewriting every other fingerprint surface they touch creates an inconsistency (a User-Agent claiming one Chrome version while the real TLS/JS engine reports another) that is itself a tell, so the recommendation is to leave both alone and let the real Chrome install report itself honestly.
Verify what changed
Patchright's own testing claims passes against detection systems including Cloudflare, Datadome, Akamai, and Kasada — but the same discipline as any anti-detect claim applies: check the actual output rather than trusting the README. Point a launched context at a fingerprint-echo endpoint and inspect what comes back, then repeat the same check with a stock Playwright launch for comparison:
from patchright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch_persistent_context(
user_data_dir="./chrome-profile", channel="chrome", headless=False, no_viewport=True,
)
page = browser.new_page()
page.goto("https://bot.sannysoft.com")
page.screenshot(path="patchright-check.png", full_page=True)
browser.close()
A stock Playwright launch fails several of that page's automation-detection rows outright (navigator.webdriver, the Chrome-headless UA check, missing plugins); Patchright's patched driver clears those specific rows. What it does not change is the WebGL row — see below.
What Patchright doesn't fix
Patchright is explicit about its own scope. Its README states plainly that it "only patches CHROMIUM based browsers" — Firefox and WebKit are unsupported, full stop, not a partial or degraded mode. That single line is the reason Crawlora's own stealth-browser engine benchmark matters here: we tested patchright directly against a real detector and a live Cloudflare Bot Management target, and it tied every other Chromium-based engine we ran (a native-spoofing fork, a CDP-direct driver) on a WebGL vendor/renderer check — all of them failed it, because headless Chromium has no real GPU context behind it regardless of which layer patches the automation leaks. Camoufox, the one non-Chromium engine in that same benchmark, was the only one that passed.
Two more things it doesn't claim to fix: its own README says Patchright passes most, not all, of Playwright's internal test suite, with a documented list of known gaps the maintainers consider low-impact for typical use rather than fully resolved. And like every engine in this series, it says nothing about IP reputation — a Patchright session with a flawless CDP-level fingerprint from a flagged datacenter IP is still a flagged datacenter IP to a vendor that scores that signal independently. See proxies for web scraping, explained for the layer no browser engine touches.
Patchright vs. the rest of the stealth-browser field
- Already have a Playwright scraper and the block is CDP/automation-detection, not WebGL: Patchright is close to a zero-code-change swap — same API, patched driver underneath.
- Target fingerprints WebGL rendering specifically: Patchright's Chromium foundation fails this in our testing regardless of the CDP patches; reach for Camoufox instead.
- Need element interaction inside closed shadow roots on an otherwise ordinary target: Patchright's shadow-root patch works even when stealth isn't the goal at all.
- Already running Scrapling's StealthyFetcher: you're already on Patchright underneath — its Cloudflare Turnstile-solving sits on top of the same engine this post covers directly.
- Target's block is TLS/JA3, not browser automation detection: neither Patchright nor any browser engine fixes that layer; curl_cffi does, without launching a browser at all.
Patchright, Camoufox, and undetected-chromedriver's descendants (nodriver, zendriver) converged on the same result against a real Cloudflare Bot Management target in our own benchmark: every one of them 403'd without a residential proxy behind it. Which engine you pick changes which fingerprint and protocol checks you clear on the way there. It doesn't change whether the target's IP-reputation layer lets the request through at all.
When CDP patches aren't enough: bridge to an API
A Patchright fleet still needs the same ongoing upkeep any browser-based approach does — a real Chrome channel to keep updated, a virtual display for headful launches, residential proxies for the IP-reputation layer Patchright doesn't touch, and a different engine entirely for the subset of targets that fingerprint WebGL. Crawlora exposes the same underlying data as plain HTTPS endpoints instead:
import requests
r = requests.get(
"https://api.crawlora.net/api/v1/amazon/search",
params={"k": "mechanical keyboard"},
headers={"x-api-key": "YOUR_API_KEY"},
)
data = r.json()
for item in data["data"]:
print(item["asin"], item["list_price"], item["link"])
Browser upkeep, proxy rotation, and CAPTCHA/Turnstile solving happen behind the endpoint, and the response is normalized JSON instead of a page you keep re-selecting after every redesign. There's an official Python SDK if you'd rather not build the request by hand, and billing is pay-on-success: a blocked or failed fetch costs nothing (pricing). Web scraping vs API walks through when DIY is still the right call.
Wrap-up
Patchright fixes a real, specific problem: the CDP-level leaks (Runtime.enable, Console.enable, tell-tale launch flags) that stock Playwright emits regardless of anything you patch at the page level, all while keeping Playwright's exact API. pip install patchright && patchright install chromium, then launch_persistent_context(channel="chrome", headless=False, no_viewport=True) with no custom headers: that's the whole recommended surface for the common case. Just don't mistake a clean CDP-detection pass for a solved WebGL check — that's a Chromium-wide limitation Patchright's own README doesn't claim to fix, and our benchmark confirms it doesn't in practice. Try the underlying endpoints in the playground with no code at all, or browse the docs for the full catalog.
Skip the browser-and-proxy stack on hard targets
Structured endpoints, managed proxies and rendering, pay-on-success billing. 2,000 free credits/month, no card.
Related reading
- Web scraping with Camoufox: the patched-Firefox engine that passes the WebGL check our benchmark says Patchright fails
- Web scraping with Scrapling: its StealthyFetcher class runs Patchright as its stealth engine since v0.3.13 — this post covers that same engine directly
- Our stealth-browser engine benchmark: the Patchright/Camoufox/zendriver test this post's WebGL claim is sourced from
- Stealth browser fleet benchmark: 15 engines, including Patchright, measured at scale
- Web scraping with curl_cffi and curl-impersonate: the TLS-fingerprint layer no browser engine, Patchright included, touches
- How websites prevent web scraping in 2026: the full detection-layer landscape Patchright sits inside
- Proxies for web scraping, explained: the IP-reputation layer CDP patching doesn't touch
Frequently asked questions
What is Patchright used for?
Patchright is a patched fork of Playwright that fixes CDP-level automation leaks — most notably the Runtime.enable and Console.enable protocol calls stock Playwright issues, which are themselves observable by a detector independent of any page-level JavaScript. It's used as a drop-in replacement for Playwright against targets that fingerprint the automation driver itself rather than (or in addition to) the browser's JavaScript-visible properties.
Is Patchright a drop-in replacement for Playwright?
Yes — the API is identical. Swapping from patchright.sync_api import sync_playwright (or the async equivalent) in place of Playwright's own import, with the same chromium.launch(), new_page(), and goto() calls, is the entire code change for the common case. The differences are underneath: a patched driver and a separately downloaded, patched Chromium build.
Does Patchright support Firefox or WebKit?
No. Patchright's own README states it only patches Chromium-based browsers; Firefox and WebKit are explicitly unsupported. For a target that fingerprints WebGL rendering specifically, that matters — Crawlora's own stealth-browser benchmark found Patchright fails that check, while Camoufox, a patched Firefox, passes it.
What is the recommended way to launch Patchright?
Patchright's maintainers recommend launch_persistent_context (not launch) with channel="chrome" to use a real Google Chrome install rather than bundled Chromium, headless=False since the stealth patches target CDP-level leaks rather than headless-mode differences, no_viewport=True, and explicitly no custom headers or user_agent, since overriding either without matching every other fingerprint surface creates a detectable inconsistency.
Does Patchright bypass Cloudflare or other anti-bot systems?
Patchright's own testing claims passes against several detection systems including Cloudflare, Datadome, Akamai, and Kasada, and it fixes the CDP-level automation leaks that trip up stock Playwright. It does not fix IP reputation (a clean fingerprint from a flagged datacenter IP is still flagged) or the WebGL fingerprint check our own benchmark found it fails — real anti-bot deployments stack these as independent layers.
What engine does Scrapling's StealthyFetcher actually use?
Patchright — Scrapling switched to it before v0.3.13, replacing an earlier Camoufox-based build. If you're already running StealthyFetcher, you're already running the same engine this post covers directly; its Cloudflare Turnstile-solving sits on top of Patchright's CDP-level patches.
Patchright vs Camoufox — which should I use?
Use Patchright when an existing Playwright scraper's block is CDP- or automation-detection and you want a near-zero-code-change swap. Use Camoufox when the target specifically fingerprints WebGL rendering or another browser-level signal a patched Firefox handles differently than a patched Chromium — Crawlora's own benchmark found this is the one axis where the two engines' results actually diverge.
