nodriver vs Playwright: Which Should You Use in 2026?

nodriver vs Playwright: Which Should You Use in 2026?

Short answer: Playwright unless you are specifically fighting automation-flag detection. It has the cross-browser support, the mature selector and waiting API, the tooling and the community. nodriver wins on exactly two axes — ~80–120MB per instance against Playwright's ~200MB, and it never fires the Runtime.enable CDP call that modern detection systems flag. It buys those with a smaller API surface, Chrome-only support, and a hard ceiling: it does nothing about behavioural scoring, so DataDome, Akamai Bot Manager and PerimeterX still block it.

The trap is assuming nodriver is "Playwright but stealthier". It is lighter and quieter at the protocol layer, and that is a narrower advantage than it sounds.

Choose Before You Read

Your situation Use
General browser automation, testing, cross-browser Playwright
Blocked specifically by automation-flag detection nodriver
Memory-bound: many concurrent browsers on one box nodriver
Target runs DataDome, Akamai or PerimeterX Neither — see below
Node.js codebase Playwright (nodriver is Python)
You need the data, not a browser fleet Neither — see below

The Architectural Difference in One Paragraph

Playwright is a full automation framework. It drives Chromium, Firefox or WebKit over a WebSocket bridge, and gives you page.goto(), auto-waiting selectors, network interception, tracing, codegen and a test runner. That bridge is what makes the API pleasant. It is also what leaves a signature.

nodriver removes the framework. It drives Chrome directly over the Chrome DevTools Protocol with no intermediate layer and without the automation flags that expose headless status. Crucially, it avoids the Runtime.enable CDP call — a command detection systems specifically watch for, because a real user's browser has no reason to issue it. No bridge process also means no bridge memory: ~80–120MB per instance against Playwright's ~200MB.

So the trade is legible: you give up API surface and cross-browser support, and you get a lighter, quieter process.

Memory Is the Real Advantage, Not Stealth

This is the part that gets buried under the stealth framing, and it is the one that changes capacity plans.

Playwright + Chromium nodriver
Memory per instance ~200MB ~80–120MB
Instances on a 16GB box (leaving 4GB headroom) ~60 ~100–150
Browsers supported Chromium, Firefox, WebKit Chrome only
Language Python, Node.js, Java, .NET Python
Auto-waiting selectors Yes Manual
Test runner, tracing, codegen Yes No
Runtime.enable fired Yes No

On a memory-bound box, nodriver roughly doubles your concurrency for the same hardware. If your bottleneck is "how many browsers fit on this machine" rather than "which sites block me", that is the whole case — and it is a better case than the stealth one.

But price the other side honestly. Playwright's auto-waiting is not a convenience feature; it is the thing that stops flaky scrapers. Writing manual waits across a few hundred page shapes is real, recurring work, and it fails in the worst way — intermittently, under load, on the pages you check least often.

The Behavioural Wall Both Hit

Here is the ceiling nobody prices before committing.

nodriver's stealth is protocol-level. It removes the tells that come from how the browser is being driven. What it does not do is fake human behaviour: it does not generate mouse movement, scroll events, or realistic keystroke timing.

Modern enterprise anti-bot systems score behaviour heavily. So:

Anti-bot system Playwright (vanilla) nodriver
Basic detection, no active WAF Passes Passes
Cloudflare BotFight (free tier) Blocked (passes once hardened) Passes
Cloudflare Enterprise / Turnstile Blocked Blocked
DataDome Blocked Blocked
Akamai Bot Manager v4 Blocked Blocked
PerimeterX / HUMAN Blocked Blocked

Read the right-hand column carefully. nodriver upgrades you from "blocked by things that check for automation flags" to "blocked by things that score behaviour". If your target is on the bottom four rows, switching to nodriver does not help — and the hours spent porting are hours not spent on the actual fix.

That is the single most common wasted migration in this space: reaching for a stealthier driver to solve a problem that is not a driver problem.

Diagnose before you port

  • 429s or sudden 403s after a burst — rate limiting. A quieter driver sending the same burst gets blocked identically.
  • Connection refused outright rather than challenged — datacenter IP reputation. No driver fingerprint rescues a refused connection; that is a proxy problem.
  • Challenge page served consistently — behavioural or fingerprint scoring. This is where a stealth browser like Camoufox belongs, not a lighter driver.
  • Works once, fails on repeat — session and navigation patterns. Hitting 500 URLs in catalogue order with no referrer reads as automation regardless of driver.

Our full diagnostic is in scraping without getting blocked.

nodriver vs Camoufox

These two get compared constantly and they are not substitutes — they sit at opposite ends of the same axis.

nodriver is the lightest option. ~80–120MB, protocol-level stealth, no behavioural handling. Fast, cheap, stops at basic protection.

Camoufox is the heaviest option. A Firefox fork with stealth patches applied at the C++ level, 0% headless detection on standard bot-detection tests (vendor benchmark, checked September 2026) — and an average of 42.49 seconds to clear a Cloudflare Turnstile challenge, at 200MB+ per context. That is roughly 85 challenged pages per hour per worker.

nodriver Camoufox
Memory ~80–120MB 200MB+ per context
Throughput on challenged pages n/a — it gets blocked ~85/hour/worker
Cloudflare Enterprise Blocked Passes
DataDome / PerimeterX Blocked Passes
Browser Chrome Firefox fork
Right when Volume is high, protection is light Data is high-value, volume is bounded

Choosing between them is really choosing between throughput and access. If the sites you need do not fight back, nodriver gets you far more pages per euro. If they do, nodriver gets you zero pages and the comparison is over. The full arithmetic is in Camoufox vs Playwright.

The configuration most teams land on: route per domain. Light driver by default, measure block rate per domain rather than site-wide — a single 8% site-wide failure figure hides one target failing 90% of the time while thirty others sit at zero — and promote only the failing handful to a heavier browser with its own concurrency cap.

When Playwright Is Simply the Right Answer

Worth saying plainly, because the stealth conversation crowds it out:

  • You are testing, not scraping. nodriver has no test runner, no tracing, no codegen. Playwright is a testing framework that happens to be usable for scraping; nodriver is not.
  • You need Firefox or WebKit. nodriver is Chrome-only. Cross-browser is not a feature it has a worse version of — it does not have it.
  • You are on Node.js, Java or .NET. nodriver is Python.
  • Your team is more expensive than your servers. Auto-waiting selectors, a mature debugging story and a large community are worth more than 100MB per worker at almost any realistic salary-to-hosting ratio.

The memory argument only wins when you are genuinely running enough concurrent browsers for 100MB each to show up on an invoice. Most teams are not, and adopt nodriver for stealth reasons that do not survive contact with their actual block logs.

When Neither Is the Answer

Both hand you a way to drive a browser. Neither hands you data.

What stays yours either way: writing selectors and rewriting them after every redesign, running and rotating proxies, session management, retry logic, storage, change detection, and the matching layer that turns rows into a usable comparison. The driver is the part of this problem that attracts the most attention and consumes the least ongoing time.

ScrapeWise sits above the whole layer: we run the browsers, the stealth tooling, the proxies, the anti-bot escalation and the parsers, and deliver structured rows through the portal data grid, a CSV or Excel export, or the REST API. Whether a given page needed a light CDP driver or something much heavier is our problem, not a line item on your capacity plan.

The honest trade-off: ScrapeWise is a data feed, not an automation framework. If you are building custom browser automation — testing, agents, anything interactive — Playwright is the right tool and we are not a substitute for it. For data delivery there is less to weigh: no plan, no compute units, a balance you top up from €5 that never expires, and a charge per delivered page from €0.15 per 1,000 plain pages (€0.75 rendered, €1.50 for residential proxies on the hardest targets), with 5 free requests on every new account.

You can also call ready-made scraping API endpoints directly.

So Which Should You Pick?

  • Playwright — your default, and correct for nearly all browser automation. Cross-browser, multi-language, auto-waiting, and the tooling that keeps scrapers from going flaky.
  • nodriver — you are on Python, memory-bound, and blocked specifically by automation-flag detection on otherwise light targets. Roughly double the concurrency per box.
  • Camoufox — the target runs DataDome, Akamai or Cloudflare Enterprise. Neither of the above gets through; plan for ~2,000 pages per worker per day.
  • Routed — light driver by default, heavy browser promoted per domain on measured block rate.
  • Neither — you want rows on a schedule and would rather not run a browser fleet to get them.

For the full matrix of which tool clears which anti-bot system, see Playwright stealth in 2026, and Patchright vs Playwright if you are on Node.js and unwilling to adopt Python or Firefox.

Paste a URL your current tool cannot reach

See why teams switch to ScrapeWise. 97% accuracy benchmark, no per-SKU pricing.

97% accuracy on Amazon benchmarks · no credit card · book a 15-min call →

FAQ

Frequently asked questions

What teams ask when Playwright gets blocked and nodriver looks like the lighter fix.

Only for a narrow slice of what Playwright does. nodriver drives Chrome directly over the Chrome DevTools Protocol with no framework layer, so you lose auto-waiting selectors, cross-browser support, the test runner, tracing and codegen. It is Python-only and Chrome-only. What you gain is roughly half the memory per instance and a quieter protocol signature. For testing, cross-browser work, or any Node.js, Java or .NET codebase, Playwright is not replaceable by nodriver.

Roughly 80 to 120MB per instance against Playwright plus Chromium at around 200MB. On a 16GB box leaving 4GB of headroom, that is about 100 to 150 concurrent instances instead of roughly 60 — close to double the concurrency for the same hardware. This is the strongest argument for nodriver and the one least often made. It only pays, though, if you are genuinely running enough concurrent browsers for 100MB each to appear on an invoice. Most teams adopt nodriver for stealth reasons that their own block logs do not support.

Past basic detection and Cloudflare's free tier, generally yes. Past Cloudflare Enterprise, DataDome, Akamai Bot Manager v4 or PerimeterX, no. nodriver's stealth is protocol-level — it avoids the Runtime.enable CDP call and the automation flags that expose headless status. It does not fake mouse movement, scroll events or keystroke timing, and those systems score behaviour heavily. Switching to nodriver upgrades you from blocked-by-flag-detection to blocked-by-behavioural-scoring, which on those four targets is the same outcome.

Runtime.enable is a Chrome DevTools Protocol command that switches on runtime evaluation over the debugging connection. Automation frameworks that drive a browser through a bridge issue it as a matter of course; a real user's browser has no reason to. That makes it a clean, cheap tell, and modern detection systems watch for it specifically. nodriver's architecture skips the bridge entirely, so the call is never made. It is a genuine advantage — just a single-signal one, which is why it stops mattering against systems that score dozens of signals including behavioural ones.

They sit at opposite ends of the same axis, so the answer follows your targets rather than your preference. nodriver is the lightest option at 80 to 120MB with protocol-level stealth only. Camoufox is the heaviest — a Firefox fork patched at the C++ level, reporting 0% headless detection on standard tests, at 200MB+ per context and an average 42.49 seconds to clear a Cloudflare Turnstile challenge, which works out to roughly 85 challenged pages per hour per worker. If your sites do not fight back, nodriver delivers far more pages per euro. If they do, nodriver delivers zero. Most teams end up routing per domain rather than standardising on either.