Why Chromium Merged Headless and Headful Browser Binaries
The Chromium team unified its separate headless browser implementation with the standard headful browser binary to eliminate maintenance overhead, fix behavioral discrepancies, and bring full feature parity to automated testing. Previously, Headless Chrome operated as an entirely distinct application built solely on Chromium's core content layer, which meant it lacked critical features found in the regular browser, most notably Chrome extension support. By merging the two implementations into a single unified architecture, developers and quality assurance engineers now interact with the exact same browser engine and feature set, regardless of whether a graphical user interface is rendered on the screen.
The Problem with the Original Architecture
When Headless Chrome was first introduced in Chrome 59, it was not
actually the Chrome browser running without a window. Instead, the
Chromium team built a separate browser application directly on top of
the content/ module—the core code required to render a page
in a sandboxed process.
The standard, headful Chrome browser is built on the
chrome/ module, which sits on top of the
content/ module. Because the original headless
implementation bypassed the chrome/ layer entirely, it was
essentially a stripped-down, alternate browser that just happened to
ship inside the same executable file.
Missing Features and No Extension Support
The most significant drawback of bypassing the chrome/
layer was the complete lack of support for Chrome extensions. Extensions
are tightly integrated into the headful browser's upper architecture.
Because the old headless mode did not use this architecture, developers
could not load extensions during automated tests or web scraping
tasks.
Beyond extensions, the old headless mode lacked many other features
implemented in the chrome/ layer, including:
- Built-in PDF viewer functionality
- Specific enterprise policies and networking configurations
- Crash reporting and metrics collection
- Certain Web APIs that relied on browser-level UI integration
High Maintenance Costs
Maintaining two separate browser implementations within the same project created a heavy burden for Chromium engineers. Whenever a new web platform feature or browser capability was added to standard Chrome, engineers had to write duplicate code to make it work in headless mode.
Often, features were added to headful Chrome but forgotten in headless Chrome. Fixing bugs also required double the effort, as patches frequently needed to be applied and tested in two different codebases.
Inaccurate Automated Testing
The primary reason developers use a headless browser is to run fast, automated tests in continuous integration (CI) environments where no monitor is attached. However, the architectural divide defeated the core purpose of testing.
Because the old headless mode was technically a different browser, a web application could pass all automated tests in headless mode and still fail when used by a real person in the standard headful browser. Subtle differences in how the two implementations handled window sizing, focus events, and network requests made testing unreliable.
The Unified Solution
To solve these issues, the Chromium team re-engineered headless mode
from the ground up, initially releasing it under the
--headless=new flag before making it the default.
Instead of launching a separate application, the unified headless mode launches the standard, full-featured headful Chrome browser and simply suppresses the creation of visible operating system windows at the platform level. By merging the implementations, the Chromium team deleted thousands of lines of duplicate code, unlocked full extension support for automation tools like Puppeteer and Selenium, and guaranteed that headless testing accurately reflects the real-world user experience.