Headless Browser vs. Real Browser: Definitions and Key Differences
Headless browsers run without a visible window, but modern Chrome Headless shares the regular browser implementation. Here’s how to choose a mode and debug it.

Short answer: A headless browser runs without showing its normal graphical window; a headed, or “real,” browser shows that window. In modern Chrome, headless mode uses the same browser implementation as headed Chrome. Headless describes how the browser is displayed and operated, not necessarily a different engine.
Use headless mode for unattended automation in CI, containers, and servers. Use headed mode when you need to watch what happens, diagnose an interactive failure, or check behavior tied to a visible window. For high-fidelity automation, make sure you know whether your tool launches modern Chrome Headless or a legacy headless shell.
1. What is a headless browser?
A headless browser performs browser work without displaying the usual graphical user interface. Chrome describes it as running “in an unattended environment, without any visible UI.” It still loads pages and can be automated to interact with them, take screenshots, generate PDFs, and inspect network or performance behavior. Chrome Headless documentation
A headed browser is the familiar visible browser window. You can see the page, watch automation interact with it, and use the browser’s normal developer tools and desktop environment.
“Real browser” is informal wording. A headless browser can be the real Chrome browser implementation; the distinction may be whether its platform windows are shown. Chrome says modern Headless creates platform windows but does not display them. Chrome’s engineering article on new Headless
2. The important distinction: modern Headless and legacy shell
Headless Chrome has changed over time. Chrome 59 introduced Headless as an unattended mode. The earlier implementation was a separate alternate browser inside the Chrome binary, so it could behave differently from headed Chrome. In 2023, Chrome described a new mode that shares code with the regular implementation. Chrome 112 introduced that unified implementation. Since Chrome 132, the old implementation is available only as the standalone chrome-headless-shell binary. Chrome Headless documentation

| Mode or binary | What it means | Good fit |
|---|---|---|
| Modern Chrome Headless | Chrome’s regular browser implementation runs without displaying its platform windows. | CI and automated tests where fidelity to current Chrome, extensions, and browser behavior matters. |
| Headed Chrome | The browser runs with a visible window. | Interactive diagnosis and checking visible-window behavior. |
Legacy chrome-headless-shell |
A separate, lightweight shell with meaningful implementation and dependency differences. | Workloads such as screenshots or scraping where its tradeoffs fit and have been validated. |
Chrome describes the legacy shell as lightweight and, for some workloads, more performant. That is not a universal speed guarantee. The shell is not interchangeable with modern Chrome for every test: Chrome recommends modern Headless for high-accuracy end-to-end and browser-extension testing. Chrome Headless documentation
3. Headless vs. headed at a glance
| Decision | Headless | Headed |
|---|---|---|
| Visible UI | No normal visible browser window. | Visible platform window. |
| Typical environment | CI/CD, containers, servers, scheduled jobs. | Local development and interactive debugging. |
| Observability | Capture logs, traces, screenshots, video, or use remote debugging because you cannot watch the window. | Watch the page and automation while it runs. |
| Browser fidelity | Modern Chrome Headless shares the regular implementation. Verify whether a tool selects the legacy shell. | Normal visible-window behavior and platform integration. |
| Resources | No visible UI to render, but browser work still consumes CPU and memory. Legacy shell can be lighter for suitable workloads. | Visible UI and desktop integration add overhead. |
Do not assume that headless is always faster. A run’s total time depends on navigation, page scripts, network conditions, waiting strategy, browser startup, and the selected browser build. The research sources provide no universal benchmark percentage for headless versus headed.
4. Which mode should you choose?
Choose headless when
- You need unattended browser work on a server, in a container, or in CI.
- You capture screenshots or PDFs as part of a repeatable workflow.
- You scrape or inspect pages and can preserve useful diagnostics for failures.
- Your CI environment does not provide a desktop display.
Choose headed when
- You need to watch a failure happen or debug focus, scrolling, dialogs, or timing.
- You are validating interactions that depend on a visible window or desktop integration.
- You need to compare the automation against what a person sees on the target platform.
For end-to-end tests
Run the mode that matches the question your test is meant to answer. Headless is convenient for unattended CI. Headed runs are useful for diagnosing failures and checking visible behavior. When accurate Chrome behavior or extensions matter, prefer modern Headless or headed Chrome over assuming the legacy shell is equivalent.
When a CI test fails, rerun the smallest reproducing case headed if your environment permits. Keep the browser version, viewport, locale, and test data fixed. Save a screenshot or trace from the headless run so the failure is inspectable even before a headed rerun.
5. Run a screenshot with Puppeteer
Puppeteer controls Chrome and Firefox using the Chrome DevTools Protocol and WebDriver BiDi. Its documented uses include navigation, screenshots, PDFs, complex UI testing, network interception, and performance analysis. Puppeteer documentation The following minimal Node.js example launches a browser, captures a full-page screenshot, and closes the browser even if capture fails.

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: 'networkidle2',
timeout: 30_000,
});
await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
await browser.close();
}
Install Puppeteer and run this as an ES module in a Node.js environment. Puppeteer’s package and browser setup can vary with the package and deployment; follow its official installation instructions. Puppeteer installation guide
To watch the same automation, switch the launch option to headless: false and run it where a graphical display is available. In Linux CI or a remote server without a display, headed mode may require a display server or a remote desktop setup.
Make the capture deterministic
- Set the viewport. Responsive layout changes with width and height. Define them explicitly for comparable screenshots.
- Choose a readiness condition.
networkidle2is convenient for many pages, but pages with persistent requests can keep the network active. A known selector or a deliberate delay after a specific UI change may be more appropriate. - Wait for lazy content. Full-page capture does not guarantee every site has loaded all below-the-fold content. Scroll through the page or wait for the site’s own loading signal when needed.
- Record failures. Log navigation errors and preserve a screenshot, console output, and trace where available. Headless runs need artifacts to replace what a developer would otherwise see in the window.
- Close resources. Always close the browser in a
finallyblock. This prevents a failed navigation or screenshot from leaving browser processes behind.
6. Choose the right automation tool and browser build
Puppeteer is a JavaScript library for browser control. Selenium WebDriver can launch Chrome with a --headless argument, and the same framework can launch a visible browser. Chrome Headless documentation Playwright documents a regular Chromium build for headed operation and a separate Chromium headless shell. It also notes that branded Chrome and Edge have switched to a newer Headless implementation closer to headed mode, so the selected browser channel matters. Playwright browser documentation
Before adopting a setup, check the tool’s browser channel and binary. Record the browser version in CI and pin it when reproducibility matters. If a discrepancy appears, check whether one environment runs Chrome, Chromium, or the headless shell before treating it as a generic “headless difference.”
7. Performance, reliability, and cost
Performance: Headless removes the visible window, but browser rendering and page execution still happen. Startup, navigation, fonts, images, JavaScript, and network waits often matter more than the visibility setting. The legacy shell may be lighter for suitable screenshot or scraping jobs, but benchmark your workload instead of assuming a fixed gain.
Reliability: Match browser version, viewport, locale, and readiness conditions across environments. Use bounded timeouts and retries only for transient errors; retries cannot fix a consistently blocked page or a selector that no longer exists. Capture diagnostics so failures can be distinguished from slow loads, changed content, or browser incompatibility.
Cost: Self-hosted automation has no per-screenshot API charge, but it consumes compute, storage, engineering time, and maintenance for browser binaries and dependencies. At scale, include concurrency limits and artifact retention in the estimate. A managed screenshot API trades browser setup and runtime maintenance for a service charge, so compare the actual workload and plan terms. The mode itself does not establish a universal cost difference.
8. Troubleshooting common problems
| Symptom | Likely cause | What to do |
|---|---|---|
| Headed launch fails in CI | No graphical display is available. | Use headless for unattended execution, or provision a display environment if visible-window behavior is the subject of the test. |
| Screenshot differs between local and CI | Browser version, viewport, fonts, locale, timing, or browser channel differs. | Align those inputs; record the selected binary and version; inspect a screenshot or trace from the failing run. |
| Navigation timeout | The site is slow, a request never settles, or the chosen network-idle condition does not occur. | Keep a finite timeout. Wait for a meaningful page selector or state rather than indefinitely increasing the timeout. |
| Blank or incomplete screenshot | Capture happened before meaningful content rendered, or scripts and assets failed. | Check navigation status, console errors, and failed requests. Wait for the page’s content signal, then capture. |
| Below-the-fold content is missing | Images or sections load lazily as they approach the viewport. | Scroll through the page or trigger the site’s lazy-load behavior before full-page capture. |
| Extension test behaves differently | The selected headless binary or channel may not match the regular browser configuration. | Use modern Headless or headed Chrome for the fidelity the test requires, and verify the actual binary. |
| Browser process remains after an error | Cleanup is skipped when an exception occurs. | Put browser shutdown in a finally block and keep timeouts bounded. |
9. Or skip the browser setup
If the job is simply to get a clean screenshot or PDF from a URL, ScreenshotNeo is a website screenshot API and MCP server for developers. It accepts one GET request and returns PNG, JPEG, WebP, or PDF. Its API documentation describes the 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
It can be used as an alternative when browser installation and maintenance are overhead for the task. Cookie banners are accepted and removed along with 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 cost nothing, and response headers say which outcome occurred. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.
10. FAQ
Is headless Chrome the same as a real browser?
Modern Chrome Headless shares the regular Chrome browser implementation, but runs without displaying its platform windows. The legacy headless shell is a distinct option with different tradeoffs.
Is headless always faster?
No universal speed advantage is established. Headless avoids displaying a window, while page execution and rendering still take resources. Measure your own workload.
Should CI tests run headless or headed?
Headless is a practical default for unattended CI. Use headed runs to inspect failures or validate visible-window behavior, and choose modern Headless when browser fidelity matters.
Does headless mean the page is not rendered?
No. The browser still processes and renders page content; it simply does not show its normal window.
Can headless automation take screenshots and PDFs?
Yes. Chrome’s automation documentation includes screenshot capture and PDF generation among Headless capabilities. Chrome Headless documentation