ScreenshotNeo

BlogGuides

What Is a Headless Browser? Features, Benefits, and Uses

A headless browser runs a browser engine without displaying its usual interface. Learn how it works, what developers use it for, and how to choose an automation tool.

By the ScreenshotNeo team4 October 202612 min read

A headless browser is a web browser that loads and processes pages without showing its usual graphical interface. It still renders pages and can run JavaScript, interact with controls, inspect the resulting page, capture screenshots, and generate PDFs. Developers use headless browsers to automate browser work in servers, containers, and continuous-integration (CI) jobs where no person needs to operate a visible window.

For example, Chrome can run headlessly from the command line and save a screenshot:

google-chrome --headless --screenshot=page.png https://example.com

Here, Chrome is the browser, --headless selects its execution mode, and --screenshot requests an output image. A browser automation framework such as Puppeteer, Playwright, or Selenium can provide a programmable way to navigate, click, type, inspect, and capture.

1. What does “headless” mean?

“Headless” means that the browser runs without displaying its normal user interface. It does not mean that there is no browser engine. The browser still loads the page and processes it as a browser does; software can drive it without a person watching or using its window. Chrome describes Headless mode as running unattended without visible UI, and says its current Headless and headful modes share the same browser implementation. Chrome Headless mode documentation

The terms describe different layers:

Layer What it does Examples
Browser Loads and processes web pages Chrome, Firefox, WebKit-based browsers
Execution mode Controls whether the usual visible interface is shown Headless or headful
Automation framework or driver Sends browser commands such as navigate, click, type, or capture Puppeteer, Playwright, Selenium WebDriver

Chrome’s documented test setup brings together a browser binary, an execution mode, and an automation tool. Keeping those parts distinct helps when diagnosing a failure: a test can fail because of the browser version, the selected mode, the automation code, or the page itself. Chrome automation and testing documentation

2. What happens when a headless browser loads a page?

  1. The browser starts. A command-line flag, automation framework, or driver launches the browser in headless mode.
  2. The browser navigates to a URL. It requests the page and its resources, then processes the page according to browser behavior and the page’s scripts.
  3. Automation can interact with the page. Code can wait, click, type, inspect elements, or observe network activity.
  4. The browser returns an artifact or result. The task might save a screenshot or PDF, serialize the rendered DOM, or report whether a test passed.

For instance, Chrome’s --dump-dom option serializes the DOM after scripts have run. That differs from simply downloading the original HTML source: the output reflects the DOM after browser-side processing. Chrome’s Headless mode engineering article

3. What are headless browsers used for?

Automated UI and end-to-end testing

A test can navigate through an application, fill in forms, click controls, and check what the browser displays or reports. Running without a visible window makes it possible to run these checks unattended in CI or a server environment. A headless run can help automate a test, but it does not guarantee that the test is reliable or that every run will be deterministic.

Screenshot capture and visual review

Automation can capture a full page or a particular part of a page. Teams can use the resulting images for visual review, documentation, or other workflows that need a browser-rendered image. The image represents the page at the time the browser captured it, so page loading, animations, fonts, viewport size, and other page conditions can affect what appears.

PDF generation

A browser can render a page to PDF for a report, a printable view, or another document workflow. The output depends on the browser’s print rendering and the page’s print styles.

Form and interaction automation

Scripts can fill in fields, submit forms, and exercise browser controls. This is useful for end-to-end checks and repetitive browser tasks, provided the automation is authorized and compatible with the site’s rules.

Rendered-page inspection

When a page builds content with JavaScript, inspecting the rendered DOM can reveal what the browser produced after scripts ran. This is useful for debugging and tests that care about the page as the browser sees it rather than only the initial response.

Network inspection and request interception

Chrome documents network request interception as an automation capability. It can be useful in tests that need to observe or control requests. The right configuration depends on the test; intercepting requests changes the conditions under which the page loads.

Cross-browser checks

Automation tooling can run tests against different browser engines or browser distributions. This helps check behavior across the browsers that matter to an application, rather than treating one browser run as proof of compatibility.

4. Benefits and limits

Benefit Practical value Limit to keep in mind
Unattended execution Runs browser tasks in CI, servers, and containers without an operator at a desktop The environment still needs a compatible browser and its required dependencies
Browser-based rendering Exercises page behavior in a browser and can produce images, PDFs, or rendered DOM output Page state, load timing, viewport, and browser version can affect output
Repeatable browser selection Pinning a browser version can tie a run to a known build Pinning helps control one source of variation; it does not make every test deterministic
Automation at scale Frameworks and infrastructure can distribute browser tests across machines More parallel work requires resources and coordination

Headless mode is an execution choice, not a promise of speed, correctness, or stability. A headless test can still be flaky if the application changes asynchronously, the test waits for the wrong condition, or the environment differs between runs. Chrome documents versioned Chrome for Testing binaries to support version-pinned environments. Chrome automation and testing documentation

5. Headless versus headful Chrome

Headful Chrome displays its normal browser interface. Headless Chrome runs without displaying that interface. Chrome’s current Headless mode shares the browser implementation with headful mode, so the distinction is about how the browser is presented and run, not a separate current browser engine. Chrome Headless mode documentation

There is historical context: Chrome’s 2023 engineering article explains that the older Headless implementation was separate from the main Chrome browser code and could differ in functionality or bugs. Chrome introduced the unified mode in Chrome 112. Since Chrome 132.0.6793.0, the old Headless implementation is available as a separate chrome-headless-shell binary. Check the current Chrome documentation when selecting a binary or command, especially if a project depends on the older behavior. Chrome’s Headless mode engineering article

6. Choose an automation tool for the job

These tools control browsers; they are not themselves browser modes. Choose based on browser coverage, language and framework fit, browser version management, and whether you need to distribute work across machines. The recommendations below are conditional on those needs, not claims that one tool is universally best.

Tool Documented fit Consider it when
Puppeteer A JavaScript library with a high-level browser control API; its documentation covers Chrome and Firefox through supported protocols. Headless is the default. Your task fits a JavaScript workflow focused on Chrome or the browser support Puppeteer documents.
Playwright Documents Chromium, WebKit, Firefox, and branded browsers such as Chrome and Edge. It distinguishes the Chromium Headless shell from newer Chrome Headless mode. You need coverage across multiple browser engines or branded browsers.
Selenium WebDriver-based browser automation, with multi-browser and multi-operating-system testing and Selenium Grid for distributing tests across machines. You already use WebDriver or need a distributed Grid setup.

Sources: Puppeteer documentation, Playwright browser documentation, and Selenium documentation.

7. Run Chrome headlessly from the command line

For a quick local capture, install Chrome and run it with the required output option. The examples use the current Chrome Headless mode; command availability can depend on your Chrome installation and version.

Save a screenshot

google-chrome --headless --screenshot=page.png https://example.com

On systems where the executable has a different name or location, substitute the installed Chrome binary. To capture a page at a chosen viewport, Chrome’s automation documentation describes virtual screen configuration; check the current command-line documentation for the exact options supported by your installed version. Chrome automation and testing documentation

google-chrome --headless --print-to-pdf=page.pdf https://example.com

PDF output follows browser print rendering and the site’s print styles. If the result looks different from the on-screen page, inspect the page’s print CSS and the browser’s print settings.

Inspect the rendered DOM

google-chrome --headless --dump-dom https://example.com

This emits the DOM after page scripts have run. It is not the same as saving the original response body.

Use a pinned browser build in CI

  1. Choose the browser and version that the project supports.
  2. Install or use a versioned browser binary in the CI environment.
  3. Run the browser in headless mode with the same options used by the job.
  4. Record the browser version and relevant test configuration when diagnosing differences between local and CI results.

Chrome for Testing provides versioned browser binaries for automation workflows. Pinning the browser makes the chosen build explicit, though other environment and page variables can still affect a run. Chrome automation and testing documentation

8. Automate a capture with Puppeteer in Node.js

This runnable example launches Chrome through Puppeteer, opens a page, waits for the page’s load event, and saves a screenshot. Install the package and its browser as described by the current Puppeteer setup instructions. Puppeteer documentation

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 900 });
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}

Save the file as capture.mjs and run node capture.mjs after installing Puppeteer in the project. The finally block closes the browser even if navigation or capture fails. For pages that continue updating after the load event, wait for a page-specific selector or condition rather than assuming that one generic wait means all content is ready.

9. Reliability, performance, and cost considerations

Make runs easier to reproduce

  • Pin the browser version where repeatable CI behavior matters, and update it deliberately.
  • Use a consistent viewport and browser configuration for visual comparisons.
  • Wait for a meaningful page condition, such as a selector that marks the content as ready.
  • Capture diagnostic output, including browser version and error details, when a job fails.

These practices reduce avoidable differences; they do not guarantee deterministic output. Network behavior, page data, timing, and the execution environment can still vary.

Keep capture work efficient

  • Use the smallest viewport and capture area that meet the requirement.
  • Close the browser when the job finishes, including on errors.
  • For parallel work, account for the browser processes and machine capacity required by each concurrent job.
  • Wait for a specific readiness condition instead of applying unnecessarily long fixed delays.

The research sources document automation features and scaling approaches, but do not establish a universal speed comparison between tools. Measure the workload and environment you plan to run.

Budget for the whole workflow

With a self-managed browser, account for the compute and maintenance needed to install, update, and operate browser binaries and automation code. A browser automation framework does not itself provide a per-screenshot price in the cited documentation; infrastructure costs depend on where and how it runs. For a hosted screenshot API, compare the plan’s included volume, price, feature coverage, and billing behavior against your expected use.

10. Troubleshooting common problems

Symptom Likely cause What to try
Chrome does not start in CI The browser binary is missing, its path is wrong, or the environment is not configured for the selected version. Confirm the installed executable and version, and make the browser installation step explicit in the CI job.
The screenshot is blank or incomplete The capture ran before the relevant page content appeared, or the page did not finish loading as expected. Wait for a page-specific selector or application readiness condition, then capture. Check navigation errors and the page at the same URL.
The page looks different from local Chrome The browser version, viewport, page state, or environment differs. Compare browser versions and viewport settings; pin a version for the test environment and capture the same state.
A test passes locally but fails in CI Timing, browser installation, machine conditions, or external page behavior may differ. Log the browser version, wait for explicit page conditions, and inspect the failure output rather than relying on a fixed delay alone.
PDF output has unexpected pagination Print styles or page layout affect browser print rendering. Inspect the page’s print CSS and verify the PDF using the same browser version and configuration as the job.
--dump-dom output differs from page source The command outputs the DOM after scripts have run, not just the original HTML response. Use the rendered DOM if that is what the test needs; inspect the original response separately when source HTML is the target.
Old Headless behavior is missing Recent Chrome versions distribute the historical implementation as the standalone Headless shell. Check the Chrome version and current documentation, and use the appropriate binary for the project’s requirement.

11. Capture a screenshot without managing a browser

If the goal is to get a page image rather than operate a browser yourself, ScreenshotNeo is a website screenshot API and MCP server for developers. The call below returns a screenshot from one GET request. See the ScreenshotNeo API documentation for the supported request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

The Node.js example uses Bun’s file-writing helper. In a Node.js project, save the response bytes with the filesystem API:

import { writeFile } from 'node:fs/promises';

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo accepts cookie and consent banners as a visitor would and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients such as Claude and Cursor.

The API supports full-page and CSS-selector captures, dark mode, device presets and custom viewports, retina scale, PDFs, HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, selector/delay/network-idle waits, request and resource blocking, headers, cookies, user agent and Authorization, timezone and geolocation, transparent backgrounds, image resizing, configurable cache TTL, signed links for public image tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Its parameter names also work with those used by other screenshot APIs, which can ease migration.

Plans include 1,000 screenshots per month free with no card; Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is available on every plan.

Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card required.

12. Frequently asked questions

Does headless mean the browser cannot run JavaScript?

No. Headless describes running without the visible browser interface. The browser still processes web pages, including scripts.

Is Puppeteer a headless browser?

Puppeteer is an automation library that controls a browser. Headless is the browser’s execution mode; Puppeteer documents headless as its default.

Does headless mode make a test reliable by itself?

No. It enables unattended browser execution. Stable tests still depend on appropriate waits, controlled browser versions, and the page and environment being exercised.

Can headless browsers make PDFs as well as screenshots?

Yes. Chrome documents both screenshot capture and PDF generation in headless automation workflows.

When should I use a screenshot API instead?

Use one when you need a screenshot result and prefer not to install and operate browser binaries and automation code for that task. Check that the API’s options, billing rules, and output formats fit your use case.