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.