Headless browsers expose subtle differences from headed browsers. Classic detection checks include: `navigator.webdriver === true` (set by WebDriver protocol automation), missing `window.chrome` object properties present in real Chrome, `navigator.plugins.length === 0` (no browser plugins installed in headless mode), unusual screen dimensions or zero-size window, and inconsistent rendering of canvas or WebGL operations due to the absence of a GPU.
Modern anti-bot systems have moved beyond simple property checks to behavioural and runtime-environment analysis: they measure JavaScript performance timing patterns, probe the browser's event loop scheduling, and verify that GPU-rendered graphics produce pixel-accurate output consistent with a real graphics driver.
Stealth libraries (puppeteer-extra-plugin-stealth, Playwright's built-in stealth mode, undetected-chromedriver) patch these detection vectors by overriding navigator properties, spoofing plugin lists, adding realistic WebGL rendering, and removing WebDriver traces from the JavaScript environment.