Skip to content

What is headless Chrome?

Headless Chrome is the Chrome browser running without a visible window. It loads pages, runs JavaScript, lays out CSS and makes network requests exactly as normal, but nothing is drawn to a screen, so it can run on servers, in CI and in containers. You control it from the command line or from a library such as Puppeteer, Playwright or Selenium.

There have been two headless modes. The original, introduced in Chrome 59 in 2017, was a separate lightweight implementation that didn't share the browser's own code, so it behaved differently in small ways. Chrome 112 added a new headless mode that is the real browser with its windows hidden. Since Chrome 132 that is the only headless mode in the main Chrome binary; the old one lives on as a separate download called chrome-headless-shell, published for every Chrome release since 120.

Which one you get depends on your tools. Running chrome --headless today starts the new mode. Puppeteer's headless: true uses the new mode and headless: "shell" the old one. Playwright uses chromium-headless-shell for headless Chromium by default and switches to the new mode when you launch with channel: "chromium". The shell is faster and lighter; the new mode behaves more like the browser people actually use.

Headless Chrome is still easy to recognise. By default its user agent contains HeadlessChrome instead of Chrome; we checked on Chrome 153, which reports HeadlessChrome/153.0.0.0. On a server without a GPU, WebGL runs on a software renderer that names itself. Frameworks also set default viewports, such as 800×600 in Puppeteer and 1280×720 in Playwright, and containers often lack the fonts a desktop would have.

Changing the user agent string is the first thing people try, and it isn't enough: the UA Client Hints, the renderer, the fonts and the screen all still describe a headless server. The common advice for automation that needs to look like a desktop is to run headed Chrome under a virtual display (Xvfb on Linux) instead, which removes the headless-specific differences. Clearcote's official Docker image runs that way by default, and the engine keeps the GPU, fonts, screen and user agent consistent with one persona. See deployment and recommendations.

Related reading

Q&AWhat is a headless browser?A headless browser runs a full browser engine with no visible window — same rendering and JavaScript, driven by code. It's the backbone of automation, and a frequent detection target.Q&AHow is a headless browser detected?Detectors probe for headless tells: automation launch flags, missing or inconsistent browser APIs, software-render shortcuts, and behavior that differs from a windowed browser.Q&AWhat are User-Agent Client Hints (UA-CH)?UA-CH are structured headers and JS APIs that report browser brand, version, platform and bitness. They must agree with the User-Agent string — a mismatch is an easy tell.Q&AWhat is WebGL fingerprinting?WebGL fingerprinting reads the GPU's render output plus driver strings (UNMASKED_VENDOR/RENDERER) and parameter limits — highly device-specific, and hard to fake coherently.DocsDeployment — Docker & CDP endpointRun Clearcote as a stealth CDP endpoint: the official Docker image, serve(), and attaching Playwright, Puppeteer or browser-use over CDP with no code change.CompareClearcote vs SeleniumBaseSeleniumBase is a big, well-maintained Python automation framework, and its UC and CDP modes are the most active stealth option in the Selenium world. They change how the browser is driven, not what it reports: the fingerprint is still your machine's. Clearcote changes it in the engine, and SeleniumBase can run on top of it.ResearchHow automation gets caught, layer by layerFrom the WebDriver flag to the TLS handshake — the distinct layers a detector reads, and why fixing one rarely helps.

Clearcote puts this into practice

An open-source Chromium with fingerprint control compiled into the engine. A drop-in for Playwright & Puppeteer.

Free for one browser with GitHub. No card.