Tony Wang7 min readundetected-chromedriver, nodriver, Playwright-Stealth, Camoufox: 4 Engines, One Real Test
We ran ChromiumFish, patchright, camoufox, and zendriver against a free detector and a live Cloudflare target. All four tied — for different reasons.
If you're searching "undetected-chromedriver vs. nodriver vs. Playwright-Stealth vs. Camoufox," you're really asking which of four different engineering approaches to browser stealth actually works. We already benchmarked three of them against a real anti-bot target. This time we added a fourth — architecturally the most different of the bunch — to see whether the pattern held.
Round 1: bot.sannysoft.com, all four engines
| Engine | Approach | Core tests | WebGL vendor/renderer |
|---|---|---|---|
| ChromiumFish | Native C++/Blink spoofing | 8/8 pass | FAIL |
| patchright | JS-patched Chromium | 8/8 pass | FAIL |
| camoufox | Patched Firefox | 7/8 pass (Chrome-only test N/A) | PASS |
| zendriver | CDP-direct, persistent session | 8/8 pass | FAIL |
Same story as the first bench, now with a fourth data point confirming it: whether an engine spoofs a fingerprint natively, patches it with JS, or drives a real Chrome directly over CDP, the core stealth checks come back identical. WebGL is still the one Chromium-shaped hole — three of four fail it, the Firefox-based outlier doesn't.
The one genuine engine-level difference we found this round wasn't on the checklist at all. ChromiumFish, patchright, and camoufox each present a spoofed Windows user agent. zendriver doesn't bother — it reports exactly what it is, X11; Linux x86_64. That's not obviously worse: a truthful OS string is one less thing that has to stay coherent with the rest of the fingerprint (WebGL renderer, font list, navigator.platform), and a mismatch between a claimed OS and any of those is a much more common anti-bot tell than "this is Linux." We don't have data on which strategy anti-bot vendors actually weight more heavily — it's worth knowing the engines make different bets here, not just that they use different spoofing mechanics.
Round 2: the same real target, now with a 4th architecture
| Engine | nowsecure.nl (public JS-challenge demo) | g2.com (real Bot Management) |
|---|---|---|
| ChromiumFish | PASS | 403 |
| patchright | PASS | 403 |
| camoufox | PASS | 403 |
| zendriver | PASS | 403 |
Full consensus, 4 for 4 both ways. Every engine cleared the soft public demo. Every engine hard-403'd on the real Bot Management target — the exact same small Cloudflare block page (<title>g2.com</title>, the #cmsg challenge-injection marker), byte-for-byte the same shape our first bench saw from the other three engines.
This is the part worth sitting with: zendriver isn't a variation on the same theme as the other three — it's a structurally different way of controlling a browser, a persistent session over raw CDP instead of a fresh spawn-per-request HTTP service. If engine architecture mattered to a real anti-bot vendor's decision, this is exactly the kind of difference that should have shown up. It didn't. (We didn't re-run the proxy round from our first bench here — see that post for the datacenter-proxy-pool result, which applies to this target regardless of which engine is driving it.)
What actually differs between these four engines
Stack both benches and the differences that are real are not the ones "stealth browser" content usually leads with:
- Camoufox is the only one that passes WebGL cleanly, because it's the only one not running headless Chromium.
- zendriver tells the truth about its OS; the other three spoof Windows. Different bets, no measured pass-rate difference either way.
- zendriver's session model is architecturally distinct — one long-lived browser vs. fresh-per-request — which matters for latency and resource use at scale, not for whether a given request gets through.
- Every other axis we could measure — the ones "native vs. JS-patched vs. CDP-direct" marketing pitches usually center — was a tie. Passing a real Cloudflare Bot Management target came down to IP reputation in the first bench, and a 4th, architecturally different engine landed on exactly the same wall.
The bottom line
If you're choosing between undetected-chromedriver's successors, playwright-stealth-style patching, and a patched-Firefox approach, the honest answer from two benches now is: pick based on maintenance burden and ecosystem fit, not stealth. None of the four approaches we tested — native spoofing, JS patching, Firefox patching, or CDP-direct control of a real browser — moved the needle against a target that's actually checking IP reputation. The lever that does is the one neither this post nor the last one found in the browser at all.
How we did this (and the caveats)
zendriver required a different bench method than the other three. ChromiumFish, patchright, and camoufox each expose a simple POST /fetch HTTP contract; zendriver exposes a raw CDP WebSocket behind a host-header-rewriting proxy, so we drove it with Playwright's connect_over_cdp from inside another pod in the same cluster, fetching a fresh browser context per test (matching the isolation the other three get by default, since zendriver's browser process itself is shared/persistent).
nodriver itself wasn't tested — it's currently scaled to 0 replicas in our fleet. zendriver is presented here as its closest live equivalent (an actively-maintained fork of the same codebase), not as nodriver itself.
Same small-sample caveats as the first bench apply: one free detector, two live targets (one soft, one hard), single sequential requests. This is a benchmark, not a load test, and it measures four specific engines, not every implementation of "native spoofing" or "CDP-direct control" that exists.
Skip choosing between four engines yourself
Crawlora's fleet runs all of these approaches behind one API and routes around whichever one a target is currently blocking. 2,000 free credits a month, no card required.
Frequently asked questions
Is nodriver or zendriver better for undetected browser automation?
In our fleet, nodriver itself is currently scaled to 0 replicas — zendriver, its actively-maintained fork, is what's actually running. On our bench, zendriver tied every other engine on stealth-specific tests and hard-403'd on a real Cloudflare Bot Management target exactly like the other three, so the choice between the two forks likely comes down to maintenance activity and API stability, not measured stealth.
Is Playwright-Stealth still effective against Cloudflare in 2026?
The JS-patched-Chromium approach (patchright in our bench, the same idea as playwright-stealth) passed every free-detector test we ran — 8/8 core on bot.sannysoft.com. Against a real Cloudflare Bot Management target it hard-403'd, at the exact same rate as three other completely different engines. The patching itself works; it's not what a real anti-bot deployment is actually checking.
Does camoufox beat Cloudflare better than Chromium-based stealth browsers?
Not against the real target in our bench — camoufox hard-403'd on a Cloudflare Bot Management site exactly like the three Chromium-based engines we tested alongside it. Where camoufox did measurably differ: it's the only one of the four that passes bot.sannysoft.com's WebGL check, because it's the only one not running headless Chromium without a GPU.
Does a CDP-direct browser like nodriver or zendriver behave differently from a JS-patched one like playwright-stealth?
Architecturally, yes — zendriver (CDP-direct) runs one persistent browser session behind a raw WebSocket, while patchright (JS-patched) spawns a fresh browser per request behind an HTTP contract. Against a real anti-bot target in our bench, that architectural difference didn't change the outcome: both hard-403'd on the same Cloudflare Bot Management site at the same rate.
Why does zendriver use a Linux user agent instead of spoofing Windows?
Unlike the other three engines in our bench (ChromiumFish, patchright, and camoufox all present a spoofed Windows UA), zendriver reports its real Linux environment honestly. Neither approach changed the pass rate against the real anti-bot target we tested, but an honest OS string has one practical advantage: it's one fewer fingerprint field (WebGL renderer, font list, navigator.platform) that has to stay coherent with a fabricated claim.