Scrapeless Wiki

What Is nodriver? – Definition and How It Works

Informational P2 what is nodriver
Overlaps a live page. A published page already targets this keyword: https://www.scrapeless.com/en/blog/nodriver-patchright-undetected. Publishing both risks cannibalisation β€” decide before this goes live.

Learn what nodriver is, why it removes the WebDriver layer entirely, how its async CDP interface works, and how it differs from undetected-chromedriver.

nodriver is a Python browser-automation library that talks to Chromium over the Chrome DevTools Protocol with no WebDriver component at all. It comes from the author of undetected-chromedriver and is best understood as that project's conclusion: rather than keep hiding the driver, remove it.

1. Why Removing the Driver Helps

Selenium reaches the browser through ChromeDriver, a separate binary implementing the W3C WebDriver protocol. Starting a browser that way leaves observable marks β€” most famously navigator.webdriver, but also flags, switches, and behaviours that come from the driver's launch arguments rather than from your code.

undetected-chromedriver patched those marks one at a time. nodriver removes their source. There is no driver process, so there is nothing driver-shaped to detect and nothing to keep patched as Chromium changes.

2. Connecting Over CDP

The library launches Chromium and attaches to its DevTools endpoint directly. Every operation β€” navigation, evaluation, input, network interception β€” is a CDP message.

The API is asynchronous throughout:

import asyncio, nodriver as uc

async def main():
    browser = await uc.start(headless=False)
    page = await browser.get("https://example.com")
    print(await page.evaluate("document.title"))
    browser.stop()

asyncio.run(main())

There is no synchronous wrapper, so nodriver assumes an async codebase. Porting a synchronous Selenium suite means restructuring it, not swapping an import.

3. Element Handling

nodriver finds elements by text and by selector, and it waits by default rather than requiring explicit waits at each step. page.find("Sign in", best_match=True) locates a control the way a person describes it, which survives markup churn better than a brittle XPath.

Input goes through CDP input events, so clicks and typing arrive as browser-level events rather than as synthesised DOM events. That distinction matters where a site checks whether an interaction carries trusted-event properties.

4. What It Is Not

nodriver drives Chromium only. There is no Firefox or WebKit path, and no cross-browser abstraction β€” it trades portability for directness.

It is also not a fingerprint tool. It removes the automation tells that a driver introduces, but the browser still reports its real screen, timezone, fonts, and WebGL strings unless you change them, and it still connects from whatever IP you gave it. Sites that profile the network path or the fingerprint see exactly what they would see from any other Chromium.

5. Where It Fits

nodriver suits Python collection work against Chromium targets that inspect for driver artefacts, where an async design is acceptable and cross-browser coverage is not required. For an existing Selenium suite that needs the same benefit without a rewrite, a patched-Selenium approach fits better; for teams already on Playwright, the equivalent move is a patched Playwright build.

6. Summary

nodriver is an async, driver-free Python library that automates Chromium straight over CDP, eliminating the WebDriver artefacts that stealth patches otherwise chase. It handles waiting well and sends real browser input events. It is Chromium-only, async-only, and deliberately silent on fingerprints and IP reputation.