Web Scraping APIs

What Is PatchRight?

What Is PatchRight? — conceptual illustration
On this page

PatchRight is a browser-automation library that edits Playwright's own Python code before Chrome launches, instead of injecting JavaScript into the page after it loads. Why does that matter? Anti-bot systems like Kasada can ask the browser to show the source of its built-in functions using Function.prototype.toString() — and if they see hand-written JavaScript there, they can tell the function was modified at runtime. PatchRight leaves nothing in the JavaScript to read, because its changes happen at the Python-to-Chrome bridge, below any code the page can inspect. This makes it a common choice for browser automation on JavaScript-heavy sites you are permitted to access, where runtime-injection tools like playwright-stealth leave a detectable signature.

Quick facts

Patch levelPython source (Playwright bindings), pre-Chrome
Why it worksNo JS runtime modifications — Function.toString() finds nothing
Main use caseSites that inspect function source (where runtime-patch signatures are visible)
Drop-in?Mostly — playwright API compatible with minor adjustments
Installpip install patchright

The architectural difference

playwright-stealth hides a bot by injecting JavaScript into the page (via Page.addInitScript) that rewrites built-in browser properties — navigator.webdriver, WebGLRenderingContext.prototype.getParameter, HTMLCanvasElement.toDataURL, and dozens more. The trick works, until an anti-bot script asks to see the source of one of those rewritten functions: Function.prototype.toString.call(navigator.__lookupGetter__("webdriver")). A genuine browser function answers [native code]; a patched one shows the injected JavaScript instead. At that point the patch itself becomes the giveaway.

PatchRight takes a different route. It edits Playwright's Python source so the underlying CDP commands (CDP - the Chrome DevTools Protocol, the channel Playwright uses to steer Chrome) are sent in a way that achieves the same result without ever touching JavaScript. The browser's built-in functions are left exactly as they were, so Function.toString() still returns [native code] — there was no JavaScript patch to expose.

Where PatchRight fits

JavaScript-heavy sites that inspect function source. Because PatchRight avoids runtime JavaScript injection, it does not leave a Function.toString() signature the way runtime patches do. This is the main reason it exists.

Cloudflare with active Turnstile/JS challenges. On sites you are authorized to automate, a consistent browser configuration matters, and PatchRight's source-level approach is one way to keep the function-source surface consistent.

Any case where you have confirmed playwright-stealth leaves a detectable runtime signature. Switching is easy — PatchRight is a near drop-in replacement with very few API changes.

It is not the right tool for everything. It addresses only the function-source surface; it does not change the canvas/WebGL/audio fingerprint layer. For those, CloakBrowser (Chromium) or Camoufox (Firefox) work at the canvas/WebGL/audio layer instead.

What PatchRight does not address

PatchRight covers the toString-detectable surface in Playwright Python. It does not handle:

  • Canvas / WebGL / AudioContext fingerprinting — these read your GPU and hardware. Use CloakBrowser or Camoufox.
  • TLS fingerprinting — TLS is the encryption layer behind https, and it sits below the browser. Whatever TLS signature your Chromium ships with is what sites see.
  • Behavioural detection — input timing and interaction patterns. This is handled by other layers such as Botasaurus.
  • IP reputation — that is the proxy's job. Use residential or ISP static.

Think of PatchRight as one layer in a stack, addressing only the function-source surface.

Code example

python
# PatchRight is a near-drop-in replacement for Playwright Python
# Note the import path change: patchright.sync_api instead of playwright.sync_api

from patchright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context(
        proxy={"server": "http://user:pass@residential:port"},
        # ... otherwise identical to Playwright
    )
    page = context.new_page()
    page.goto("https://kasada-protected.com/")
    # PoW solved naturally by real browser execution
    html = page.content()

Related terms

What Is Kasada?
Kasada is a bot-defense system that big retailers, ticketing sites, and sneaker drops put in front of their servers to manage automated traf…
What Is Camoufox?
Camoufox is a fork of Firefox with anti-fingerprinting patches applied at the C++ build level. That phrase matters: most anti-fingerprinting…
What Is CloakBrowser?
CloakBrowser is a Chromium build with 49 C++ binary patches that give it a consistent browser configuration. The goal is for it to present l…
What Is Anti-Bot Detection?
Anti-bot detection is the set of techniques websites use to tell automated traffic apart from real human visitors — and then block, challeng…
What Is Function.toString() Inspection?
Function.prototype.toString() inspection is a technique anti-bot scripts use to identify JavaScript functions that have been modified at run…
What Is Playwright?
Playwright is a cross-browser automation framework from Microsoft that drives Chromium, Firefox, and WebKit through a single API. An automat…
Anti-Detect Browser Tools Compared
Anti-detect browser tools aim to present a consistent, real-looking browser configuration so that automated sessions render the same fingerp…
Browser Automation Engine Benchmarks
A browser-automation-engine benchmark drives several automation stacks through the same set of targets and records, side by side, how often …
How Do You Choose an Anti-Detect Browser Tool?
Choosing an anti-detect browser tool comes down to matching the tool's strengths to the detection layer you actually face - no single tool i…

Concept map

How PatchRight connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Web Scraping APIs
Building map…

Frequently asked questions

Is PatchRight a fork of Playwright?

Not really a fork — it is better described as a patched build of Playwright. It uses the same upstream codebase, with targeted edits to the Python source in the spots where Playwright would otherwise leak a toString-detectable signature. Updates from the official Playwright team still flow through.

How is this different from undetected-chromedriver?

undetected-chromedriver does one focused thing: it removes the navigator.webdriver flag from Selenium-driven Chrome, which is a small patch surface. PatchRight applies the same idea across the much larger Playwright API, where Function.toString() checks are more common. Both have their place; PatchRight covers a wider surface.

Does PatchRight handle CAPTCHAs?

No — it only deals with the function-source layer. CAPTCHAs are handled separately, for example by a solver service or by a real-browser setup that scores well on reCAPTCHA v3.

Should I use PatchRight or Camoufox?

Use PatchRight when you specifically need Chromium and the obstacle is Kasada or playwright-stealth detection. Use Camoufox when you need Firefox (for Cloudflare, or multi-vector coherence with geoip=True) or when the obstacle is canvas/WebGL fingerprinting. They are not mutually exclusive — large scraping operations often run both.

Last updated: 2026-05-31