Privacy Tech

Playwright Stealth Alternatives 2026: The Plugin Era Is Over

BC

BotCloud Team

May 4, 2026·8 min read

What Happened to puppeteer-extra-plugin-stealth

The dominant approach to anti-detection automation for the last five years has been: load a vanilla Chromium, attach puppeteer-extra-plugin-stealth, and hope. As of 2026, that approach is failing on most targets that matter — and the package itself has stopped shipping fixes.

The npm registry timestamps tell the story directly. The current version of puppeteer-extra-plugin-stealth is 2.11.2, published 2023-03-01. There has been no new release in three years. The maintainer has not formally deprecated it, but issues filed against the repo about new detection vectors are accumulating without code response.

Three years is an eternity in this space. Cloudflare, DataDome, FingerprintJS, and the rest of the detection ecosystem ship updates monthly. Detection signatures that did not exist in 2023 — Sec-CH-UA inconsistencies, JA4 fingerprinting, the cluster of CDP-injected globals on window — are the ones that matter today, and the plugin has no patches for any of them.

This post explains why the plugin model itself was structurally bound to fall behind, and walks through the current alternatives.

Why a Plugin Cannot Win This Race

The plugin model has three structural disadvantages against detection vendors:

1. Asymmetric Pace

A plugin maintainer ships fixes in their spare time. Detection vendors employ teams of engineers paid full-time to find new tells. A new detection technique that takes a vendor a week to deploy takes the plugin community months to discover, reverse-engineer, and patch. Over years, the gap accumulates into a static plugin and a moving detection target.

2. Patches Leave Patch Shapes

Any property overridden in JavaScript leaves a shape — a side effect of how the override was implemented. Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) is detectable through Function.prototype.toString audits, through the enumeration order of Reflect.ownKeys, through the timing of when the property was set relative to other page initialization. A sufficiently motivated detection script reads the patch, not the patched value.

The plugin fixes this in places — its own chrome.runtime patch handles toString correctly — but each new patch adds another candidate shape that detection can discriminate. The defense surface grows linearly with patches; the detection surface grows multiplicatively with the cluster of weak signals.

3. CDP-Injected Globals Are Out of Scope

When Puppeteer or Playwright attaches via Chrome DevTools Protocol, Chromium itself injects helper globals into the page context — names like __playwright__binding__, __pwInitScripts, __playwright_builtins__, cdc_* for ChromeDriver. These appear before any page-level JavaScript runs. The plugin can delete them on every navigation, but a detection script that reads Object.keys(window) early in the page lifecycle catches them before the delete fires.

The plugin's design — JavaScript injected from the page side after CDP attach — fundamentally cannot solve this. The fix has to be at the C++ layer where CDP attachment happens, which is upstream of where any plugin can act.

The Current Alternatives, Ranked

The active replacements for puppeteer-extra-plugin-stealth fall into three categories.

Category A: Patched Drivers

These are forks of Puppeteer or Playwright that strip the runtime artifacts at the framework layer. They handle the CDP-injected globals problem (signal 3 above) by changing how the driver attaches, but they still rely on a vanilla Chromium underneath, so JavaScript-layer fingerprinting (canvas, audio, font metrics) is unchanged from default Chrome.

ToolLanguageLast ReleaseNotes
rebrowser-puppeteer-coreNode2025-05Actively maintained Puppeteer fork; renames CDP globals to non-detectable names. Pairs with rebrowser-patches for additional surface fixes.
patchrightNode / Python2026-04Actively maintained Playwright fork in the same vein. Recent releases shipping monthly.
nodriver (Python)Python2026-04Successor to undetected-chromedriver. Direct CDP control without WebDriver protocol; sidesteps the WebDriver-specific tells.

These are the right choice if you need to keep the Puppeteer or Playwright API surface and your target's detection is concentrated on framework artifacts rather than browser fingerprint depth.

Category B: Patched Browsers

These ship a forked Chromium binary with engine-level changes, and expose the standard Puppeteer/Playwright/CDP API on top.

ToolDistributionNotes
CamoufoxOpen-source binaryFirefox-based fork with fingerprint randomization at the engine layer. Strong on canvas, audio, and font fingerprint depth; weaker on the Chrome-specific surfaces that most detection actually checks for in 2026.
BrowserBase / browser-use sandboxesHosted SaaSManaged Chromium with proprietary patches; opaque about what's actually patched.
BotCloudHostedManaged Chromium fork with engine-level fingerprint surface and per-context profile loading. The CDP attachment does not produce the runtime globals the patched-driver category has to rename.

These are the right choice if your target's detection includes browser fingerprint depth (canvas/audio/font/WebGL) and not just framework artifacts.

Category C: Solver and Bypass Services

Not direct replacements for the plugin, but worth listing because they cover a different strategic position.

ToolApproachNotes
flaresolverrHeadless browser farmReceives a request URL, returns a cf_clearance cookie. Useful for Cloudflare gating but does not handle in-session navigation.
2Captcha / CapSolverSolver servicesProduce a Turnstile/reCAPTCHA token by completing the challenge in their pool. Token validity depends on the calling IP matching trust expectations.

For Cloudflare-protected sites these often get used in addition to a stealth browser, not in place of one.

What "Engine-Level" Actually Buys

Reading the categories above, the engineering question is: why does the C++ layer matter when JavaScript-layer patches handle most cases in practice?

The answer is in the patch shape problem (signal 2 above). When the C++ Chromium build is modified to remove navigator.webdriver from the source code, the property is genuinely absent from the runtime, not absent-because-overridden. There is no Function.prototype.toString shape, no Reflect.ownKeys enumeration tell, no timing window where the property was present and then deleted. Detection scripts that look for the cluster of shapes left by JavaScript patching find none.

This is also true for the CDP-injected globals: when the C++ side does not install __playwright__binding__ to begin with, no race condition can leak it. The plugin's defense ("delete on navigation") is replaced with the engine's design ("never set in the first place").

The cost of this approach is shipping a forked Chromium binary, maintaining it through Chromium's monthly major releases, and absorbing the testing surface. Most teams do not want to do that themselves, which is why managed cloud-browser providers and Firefox-based open-source builds like Camoufox exist.

A Decision Tree

If you are choosing a stealth approach in 2026, the relevant questions:

  1. Is your target's detection concentrated on framework artifacts? (navigator.webdriver, CDP-injected globals, User-Agent claims) → Category A handles this. Pick rebrowser-puppeteer-core or patchright based on language.

  2. Does your target check browser fingerprint depth? (canvas, audio, WebGL, font metrics, hardware concurrency consistency) → Category A is insufficient. Category B is the choice.

  3. Are you paying for a managed solution or running your own? → Managed cloud-browser services handle Chromium fork maintenance for you. Self-hosting an engine-level fork through monthly upstream releases takes a dedicated team; Camoufox is the only currently-active open-source binary in this category, and it is Firefox-based.

  4. Does your target use Cloudflare with aggressive Bot Fight settings? → Combine Category B with a residential proxy. Adding Category C tokens helps for the specific challenge step but does not substitute for the IP and fingerprint requirements.

What to Do With Existing puppeteer-extra-plugin-stealth Code

If you have a working stack on puppeteer-extra-plugin-stealth and your detection targets are still passing, there is no urgency to migrate. The plugin's existing patches do not stop working when the package stops releasing.

The migration path becomes urgent when:

  • You start seeing increased CAPTCHA frequency on targets that previously passed clean.
  • New target sites you add to the stack fail outright.
  • You hit a detection vendor (FingerprintJS Pro, BotD on a fresh ruleset) that the plugin has no current patch for.

The minimum-friction migration is from puppeteer-extra-plugin-stealth + puppeteer to rebrowser-puppeteer-core — same API, fork-level fixes for CDP artifacts. From there, the next jump is to a Category B build if your detection targets need fingerprint depth.

Quick FAQ

Q: Is puppeteer-extra-plugin-stealth still maintained?

The npm package has not shipped a new version since 2023-03-01 (version 2.11.2). The repository is not formally archived, but issues about new detection vectors are not getting code responses.

Q: Why does stealth plugin fail Cloudflare?

Cloudflare's detection has added signals since 2023 that the plugin has no patches for: Sec-CH-UA Client Hints inconsistency, JA4 TLS fingerprint, the cluster of CDP-injected globals at the framework level, and per-iframe target ID auditing. The plugin's frozen patch set does not cover any of these.

Q: What replaces puppeteer-extra-plugin-stealth?

For the framework-artifact subset of its job, rebrowser-puppeteer-core (Node) and patchright (Node and Python). For the deeper fingerprint subset, a Category B browser like Camoufox or a managed Chromium-based engine-level build.

Q: Will plugin patches eventually catch up?

The structural disadvantages described above (asymmetric pace, patch shapes, CDP globals out of scope) are not fixable by working harder on the plugin. They require moving the patches from JavaScript to the engine layer, which is not what a plugin is.

Q: What about playwright-stealth (Python)?

playwright-stealth is a Python port of the same approach, with the same structural issues. As of 2026 it is in similar maintenance condition to the Node version and is being superseded by patchright, which is actively maintained.

Bottom Line

The plugin era ended structurally before it ended organizationally. puppeteer-extra-plugin-stealth shipped its last release in 2023; the detection ecosystem has shipped roughly 36 months of new signatures since then. The current right answer is to migrate to either a patched driver (rebrowser, patchright) or a patched browser (Camoufox, or a managed engine-level Chromium build), depending on whether your detection targets require framework artifact handling or browser fingerprint depth.

If you are evaluating the patched-browser path and want a Chromium-based managed option, BotCloud provides an engine-level Chromium build with a per-context fingerprint API and the standard Playwright/Puppeteer attachment surface.

#stealth#puppeteer#playwright#automation#fingerprint

Share this post