---
title: "Chromium fork for automation: 29 patches instead of a script"
description: "Why hiding automation takes a patched Chromium rather than a script, and what a fork costs to keep: releases every two weeks, rebased patches, signing, rollback."
canonical: "https://scalebrowser.net/blog/chromium-fork"
last_modified: "2026-10-08"
published: "2026-10-08"
author: "davide"
category: "stealth-tools"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://scalebrowser.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Chromium fork for automation: 29 patches instead of a script

> Why hiding automation takes a patched Chromium rather than a script, and what a fork costs to keep: releases every two weeks, rebased patches, signing, rollback.

A stealth plugin rewrites `navigator.webdriver` and a dozen other values, and a site can still tell. The usual next step is another plugin or a patched driver. We went one layer further down and build our own Chromium, and this guide covers what a fork reaches that a script cannot, and what it costs to keep one in step with Chrome.

## What is a Chromium fork for automation?

A Chromium fork for automation is a build of Chromium's source code with changes compiled into the browser, so every value a page reads comes out of the browser's own code instead of being overwritten after the page has started. The Scalebrowser engine is such a fork: it carries 29 source-level patches and no injected JavaScript, counted on 29 September 2026. A change against detection can live in three places, and each place reaches a different set of signals.

| Where the change lives | How it gets there | What it cannot reach | Examples |
| --- | --- | --- | --- |
| A script in the page | injected over the automation protocol before the page's own code runs | the TLS handshake, the rendered pixels, its own injection | puppeteer-extra-plugin-stealth, [playwright-stealth](https://github.com/Mattwmaster58/playwright_stealth) |
| A patched driver | a changed library between your code and the browser | every value the stock browser reports | rebrowser-patches, [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright), [nodriver](https://github.com/ultrafunkamsterdam/nodriver) |
| A patched browser | compiled into the Chromium or Firefox binary | how the browser is driven | [CloakBrowser](https://github.com/CloakHQ/CloakBrowser), [Camoufox](https://camoufox.com/), the Scalebrowser engine |

The table describes reach, not rank. A fork can make a value true inside the browser, and it can just as well ship a wrong value to every profile at once. That is why every patch in our engine is measured against a real Chrome on the same machine before it ships.

## Why can a script not hide the control plane?

A script cannot hide the control plane because the control plane delivers it: the automation library injects the script into every page over the same protocol a detector looks for, and an object that was rewritten can be caught in the act. The maintainers of rebrowser-patches, a set of patches for Puppeteer and Playwright, say so in their [README](https://github.com/rebrowser/rebrowser-patches):

<Quote attribution="rebrowser-patches maintainers, README">Always keep in mind: the less you manipulate browser internals via JS injections, the better. There are ways to detect that internal objects such as console, navigator, and others were affected by Proxy objects or Object.defineProperty.</Quote>

The best-known script shows where that road ends. [puppeteer-extra-plugin-stealth](https://github.com/berstend/puppeteer-extra) ships 17 evasions, has had no commit since 1 March 2023 and carried 238 open issues when we read it on 22 September 2026. One of its evasions reports, by default, the vendor "Intel Inc." and the renderer "Intel Iris OpenGL Engine" on every machine, whatever graphics card really draws the page. A value asserted by a script has nothing behind it, and a page can compare it with what the hardware produces.

Moving the change into the driver removes the injection and keeps the protocol. Ian L. Paterson ran 7 tools against 31 targets, 651 verdicts in all, and [concluded in May 2026](https://ianlpaterson.com/blog/anti-detect-browser-benchmark-patchright-nodriver-curl-cffi/) that "Playwright forks fail regardless of patch quality". Every [stealth browser](/blog/stealth-browser) can be sorted along that line: by the layer it changes, not by the number of values it rewrites. FlareSolverr, which starts one Chrome per request, is covered in FlareSolverr in 2026.

## What does a fork have to maintain?

A fork has to maintain four things a script never needs: a place on Chrome's release train, patches that still apply to each new milestone, a signature on every build, and a way back when a build turns out bad.

- **The release train.** Chrome reached stable with milestone 152 on 25 August 2026, 153 on 8 September and 154 on 22 September, and, as of September 2026, [Chromium's schedule](https://chromiumdash.appspot.com/schedule) lists 155 for 6 October: one milestone every 14 days. Browserbase, which forked Chromium for its cloud browsers, [wrote in November 2025](https://browserbase.com/blog/chromium-fork-for-ai-automation/) that it cut a full Chromium build from "3-4 days" to "about an hour" to keep up with that pace.
- **The patch rebase.** Each milestone moves the code underneath the patches. When we carried our series from 151 to 154 on 12 September 2026, 23 of 30 source diffs applied unchanged and 7 needed work by hand, 15 rejected hunks spread over 13 files.
- **Signing.** A customer installs a browser binary they cannot inspect, so every build is signed, and a signed manifest names every file with its own digest. The [engine page of the documentation](/docs/engine) describes the check at install and again at every launch.
- **Rollback.** The previous build stays installed, so going back is one command without a download, and profiles follow the pinned build in both directions.

Falling behind is the cost that never shows in a build log. A browser that reports an older Chrome than the people around it sits in the thin tail of the version distribution, and no patch in its source can fix that.

<Evidence source="Scalebrowser engine against branded Chrome on the same Windows machine, 10 and 26 September 2026">

| Date | Newest Scalebrowser engine | Branded Chrome on the same machine | Gap |
| --- | --- | --- | --- |
| 10 September 2026 | 151.0.7922.99 | 153.0.8010.37 | 2 milestones |
| 26 September 2026 | 154.0.8037.58 | 154.0.8037.57 | same milestone |

</Evidence>

On 26 September the two builds also sent the identical TLS fingerprint, JA4 `t13d1517h2_8daaf6152771_cb7bf5808d99` with 17 extensions. The version string and the handshake have to move together, because a server needs only the user agent and the extension count to find a mismatch.

<ProductMention />

## Which detection does the fork act on?

The fork acts on what the browser reports: JavaScript values, request headers, the TLS handshake and what the graphics card draws. It does not decide how the browser is driven. A page that watches for the automation protocol itself, the subject of CDP detection by pages, reads the control plane, and that layer needs its own answer in the driver and in the input path above the browser. A fork without that answer is half the work, and so is a careful driver on a stock browser. Why curved pointer paths are not enough is covered in ghost-cursor and Bezier paths.
