Undetected-ChromeDriver alternatives in 2026
undetected-chromedriver was the default fix for a caught Selenium script for years. In 2026 it's the thing getting caught. Here's what actually replaced it, compared honestly: Camoufox, nodriver, patchright, and a much cheaper trick for the requests that never needed a browser at all.
Disclosure: some links here are affiliate links. If you sign up through them we may earn a commission at no extra cost to you. We only recommend tools we'd use ourselves. Hire a Clawd is our own service.
undetected-chromedriver's pitch was simple: Selenium script gets flagged, you swap in
uc.Chrome(), problem solved. It patched the handful of tells stock ChromeDriver
leaves behind and got on with its life.
Its life has slowed down a lot since. The changelog's gone quiet. The issue tracker hasn't. And the sites it's supposed to sneak past kept shipping detection that lands below the layer uc even touches. So the question people actually search for now isn't how to use undetected-chromedriver. It's what to use instead.
Four things answer that, each solving a different slice of the problem: an async rebuild from the tool's own author, a Firefox build that fakes its fingerprint in C++, a couple of patched Playwright forks, and a plain speed trick for requests that never needed a browser in the first place. Here's each one straight, including where it still loses.
Why undetected-chromedriver is losing ground
The pitch held up for years: take real Chrome, quietly scrub the tells Selenium leaves behind,
the cdc_ variables sitting in the page source, the --enable-automation
flag, a couple of leaking navigator properties, and ship a driver that looks stock. Winning that
one fight used to be enough.
It stopped being enough once detection moved down a layer. Selenium, and everything built on it,
uc included, still drives Chrome through the DevTools Protocol, and CDP itself leaves marks no
property patch touches: a Runtime.Enable call that fires the moment automation
attaches, timing quirks in how frames report back, differences in how console events surface. A
vendor reading the CDP layer directly doesn't care what navigator.webdriver says.
It's watching the wire, not the page.
Stack that on a project that hasn't shipped a stable release since early 2024, with open issues piling up faster than anyone's closing them, and you get what people are actually reporting now: setups that used to sail through Cloudflare, stuck looping on a Turnstile that never clears. The tool isn't broken exactly. It's fighting a war it wasn't built for.
Nodriver: the same author's async rebuild
Nodriver is the most direct answer to what replaced undetected-chromedriver, because it's literally the same person's answer. After years of patching WebDriver from the outside, uc's author rebuilt the whole approach from zero instead of patching it again.
The big change isn't a new trick. It's architecture. Nodriver drops Selenium and WebDriver completely: no chromedriver.exe, no middleman server translating commands, no WebDriver protocol at all. It talks straight to Chrome over the DevTools Protocol through a websocket, and it's async first, so it drops into anything you're already running on asyncio without friction.
Cutting WebDriver out kills a whole category of tells by itself, since a chunk of what detectors
look for is WebDriver-specific plumbing that has no reason to exist once you're not using it.
Nodriver also skips some of the blunter CDP habits that give automation away, like firing
Runtime.Enable on every page the way a default Playwright or Puppeteer session does.
import asyncio
import nodriver as uc
async def main():
browser = await uc.start(headless=False)
page = await browser.get("https://example.com")
await asyncio.sleep(2)
print(await page.evaluate("document.title"))
await browser.stop()
if __name__ == "__main__":
uc.loop().run_until_complete(main())
It's young next to a decade of Selenium tooling, so the pile of tutorials and Stack Overflow answers is thinner and the errors are terser than you'd like. But it's actively developed, free of the WebDriver baggage that's slowly sinking uc, and about the closest thing to a straight upgrade if you're on Chrome and don't want to change engines.
Camoufox: spoofing at the binary level
Nodriver makes Chrome automation cleaner. Camoufox skips Chrome altogether.
It's a custom Firefox build, and the fingerprint spoofing is compiled into the browser's C++
internals instead of bolted on as a patch or an injected script. navigator, WebGL,
canvas, fonts, WebRTC, all of it reads as native, because at the engine level it is. There's
nothing sitting in the page for a detector to catch mid-patch, which is exactly the failure mode
that keeps catching every Chrome-side tool on this list.
It runs through Playwright, sync or async. pip install camoufox[geoip], a
camoufox fetch to grab the patched binary, and you're writing the same shape of
script you'd write for stock Playwright:
from camoufox.sync_api import Camoufox
with Camoufox(geoip=True, humanize=True, headless="virtual") as browser:
page = browser.new_page()
page.goto("https://example.com/")
page.wait_for_load_state("networkidle")
print(page.title())
Being Firefox is a genuine trade, not just an upside. A lot of anti-bot setups are tuned hard against Chromium and wave Firefox through without a second look, which is a big part of why Camoufox holds up where patched Chrome doesn't. A handful of Chromium-only sites act strange in it, and it's still pre-1.0, so pin your version. We go deep on setup and every option in the full Camoufox guide, and put it head to head against uc specifically in this comparison if that one matchup is all you care about.
Recommended tool
Not scripting any of this?
Everything above assumes a headless script driving the browser. If your actual job is running a stack of accounts by hand, one persistent profile per browser window, a managed anti-detect browser gets you an isolated, native-looking fingerprint per profile without compiling anything yourself.
See our anti-detect browser pick →Affiliate link, at no extra cost to you.
Patchright and rebrowser-playwright
Here's a wrinkle people miss: stock Playwright has its own version of undetected-chromedriver's
problem. It's cleaner out of the box than raw Selenium, but it still drives Chromium over CDP,
and it still fires that same Runtime.Enable call on startup we flagged above. A
detector watching for it doesn't care whether the client calls itself Selenium, Puppeteer, or
Playwright.
Patchright and rebrowser-playwright both exist to fix that, and
they take the same approach uc took: patch the specific leaks instead of rebuilding the browser.
Patchright is a maintained fork of Playwright itself, close enough to a drop-in that swapping the
import is most of the migration. It closes the Runtime.Enable leak, patches a few
console and command-flag tells Playwright leaves behind, and fixes how closed shadow roots get
exposed, which some fingerprinting scripts use to spot Playwright specifically.
pip install patchright
patchright install chromium
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()
rebrowser-playwright is the sibling project: same target, different maintainers, its own patches for the same CDP leaks, with a couple of tunable modes if you need to trade some stealth back for Playwright behavior that the aggressive patch breaks.
Both are the right call if you're deep in a Playwright codebase and don't want to rewrite it around Camoufox or learn nodriver's API from scratch. Neither changes your engine, though, so you're still fingerprinted as Chromium and still in the same arms race uc was losing, just a few rounds behind. Treat these two as buying time on existing code, not a permanent fix. More on the exact leak they're patching in our playwright-stealth writeup, if you want the deeper version of that story.
Keeping four tools patched isn't a strategy
Nodriver today, Camoufox next month, back to patchright when a target changes its mind, that's not a stack, that's a part-time job. Hire a Clawd runs the automation for you, swaps the underlying tool the moment one starts losing to a target, and you never have to know which of these four is having a bad week.
See plans from $49/mo →Real browser + curl_cffi for the no-JS cases
Every tool above assumes you need a browser for the whole job. Most scrapes don't.
Think about what a browser's actually for: rendering JavaScript, clearing a challenge, clicking through a login. Once you're past that part, a lot of what you're pulling, paginated API responses, listings, search results, doesn't need a rendering engine at all. It needs a client whose TLS and HTTP/2 handshake looks like the browser you just used, hitting the same endpoint with the same cookies.
That's what curl_cffi is for. It impersonates a real browser's TLS and HTTP/2
fingerprint at the request level, so JA4 and header order match what a detector expects from
Chrome, without spinning up an actual browser process. It's dramatically faster and lighter than
any tool above, and for requests it can handle, there's no reason to pay the RAM and CPU cost of
a full browser.
The pattern that works well: drive a real browser, Camoufox or nodriver, just long enough to load the page, clear whatever challenge shows up, and earn a valid session cookie. Then hand everything after that, every paginated request in the run, to curl_cffi using that same cookie and a matching User-Agent.
from camoufox.sync_api import Camoufox
from curl_cffi import requests as cf
with Camoufox(geoip=True) as browser:
page = browser.new_page()
page.goto("https://example.com/")
page.wait_for_load_state("networkidle")
cookies = {c["name"]: c["value"] for c in page.context.cookies()}
ua = page.evaluate("navigator.userAgent")
session = cf.Session(impersonate="chrome")
for name, value in cookies.items():
session.cookies.set(name, value)
session.headers["User-Agent"] = ua
for n in range(1, 50):
r = session.get(f"https://example.com/api/products?page={n}")
print(r.status_code, len(r.json()["items"]))
One browser launch, then forty-nine fast requests instead of forty-nine browser page loads. That's the entire trick, and it's the difference between a scrape that takes ten minutes and one that takes an hour. The moment the site throws a fresh challenge, expired cookie, flagged IP, whatever, go back to the browser and repeat.
Recommended tool
Not one of these four touches your IP
Nodriver, Camoufox, patchright, curl_cffi, doesn't matter which one you land on: run it off a bare cloud box and the target still sees a datacenter address. A rotating residential pool is what makes the fingerprint work above actually count for something.
See our proxy pick →Affiliate link, at no extra cost to you.
Head to head
Stack all four next to the fallback option and the shape of the decision gets pretty obvious:
| Tool | Engine | How it hides | Maintenance | Best for |
|---|---|---|---|---|
| undetected-chromedriver | Chrome (Selenium) | Patches the chromedriver binary, strips automation flags | Stale, last stable release early 2024 | Legacy code, very light targets |
| nodriver | Chrome (no WebDriver) | Talks straight to CDP, skips Selenium's tells entirely | Active, same author as uc | Chrome loyalists ready to drop Selenium |
| Camoufox | Firefox | Spoofing compiled into the C++ engine | Pre-1.0, active again in 2026 | Cloudflare, DataDome, the hardest targets |
| Patchright / rebrowser-playwright | Chrome (Playwright) | Patches Playwright's own CDP leaks | Actively maintained forks | Existing Playwright codebases |
| Real browser + curl_cffi | Whichever you pair it with | Browser clears the challenge once, curl_cffi impersonates it after | Depends on the paired browser | High-volume pagination and APIs |
Which one to actually reach for
So which do you actually install today? Depends on what's already true about your code and your target, roughly in this order:
- Already on Selenium, target's barely defended. Stay put. Rewriting working code for a site that isn't fighting back is wasted effort. uc still clears it fine.
- On Selenium and Chrome, ready to modernize. Move to nodriver. Same engine, same author's judgment, none of the WebDriver baggage that's slowly sinking uc.
- Facing Cloudflare, DataDome, or anything that actually fights back. Camoufox. Nothing on this list holds up better once a vendor's reading past the page itself.
- Deep in a Playwright codebase, not ready to change engines. Patchright or rebrowser-playwright buys real headroom for close to zero migration cost. You're still Chromium, still in the arms race, just a few rounds behind Camoufox.
- Scraping a lot of pages that don't need JavaScript after the first load. Pair whichever browser you picked with curl_cffi for the bulk of the run. Cheapest speed win on this entire list, and most people skip it.
None of that fixes your IP. A datacenter address gets a scraper blocked before any of the above gets a chance to matter, on any target that's actually paying for protection. Proxies aren't an alternative to picking a tool from this list. They're the layer underneath all of them.
Skip the setup
The Anti-Detect Scraping Starter Kit
A ready-to-run Camoufox and residential-proxy Python template, humanized behavior included, with a setup guide and a pre-flight checklist so you're not the one finding the fingerprint leak at 1am.
$19 one-time
Get the kit →FAQ
Is undetected-chromedriver dead in 2026?
Not dead, just falling behind. It still clears sites running light or no anti-bot protection, and a working Selenium pipeline pointed at an easy target has no real reason to move. Against Cloudflare, DataDome, or a serious in-house detector it's catching a lot more than it used to, and its own author has already moved on to build what replaced it.
What's the closest drop-in replacement for undetected-chromedriver?
If you want to stay on Chrome and keep most of your logic, nodriver is the closest thing: same author, same target browser, no WebDriver layer underneath to leak. If your code's already on Playwright, patchright is the tighter drop-in since its API is nearly identical to Playwright's own.
Is Camoufox better than nodriver?
For hard targets, yes, since it spoofs at the engine level instead of cleaning up a Chrome that's still the most-watched browser online. For a Chrome-only site or a team that doesn't want Firefox in the stack, nodriver is the better fit, even though it's the less resilient of the two against the toughest anti-bot vendors.
Do nodriver, Camoufox, and patchright still need proxies?
All three, no exceptions. None of them touch your IP address, and a clean fingerprint sitting behind a flagged datacenter IP still gets blocked on anything protected. Pair whichever tool you land on with residential proxies, and if the target's running something heavier, read the DataDome playbook too.