Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use headless mode for unattended browser automation when the chosen browser implementation matches your target; use headed mode when you need to watch the page or debug interactions visually. Headless means the browser runs without a visible window, not that it has no rendering or cannot produce screenshots. The important caveat is that “headless” does not name one identical implementation across browsers and automation frameworks.

What headless and headed mean

A headed browser opens a visible browser window. You can observe navigation, inspect the page, and watch your automation interact with it. A headless browser runs without displaying that window, which makes it a natural option for scripts on servers, in containers, and in continuous integration (CI) pipelines.

Both modes can load and render pages and run browser automation. Headless Chrome can also take screenshots, generate PDFs, support remote debugging, and use a virtual screen configuration, according to Chrome for Developers. A hidden window is therefore not the same as a browser that cannot produce visual output.

How to choose between them

Need Practical starting point What to check
Run automation unattended in CI, a server, or a container Headless Confirm that the browser binary and headless implementation match the environment you need to test.
Watch clicks, navigation, or other interactions while debugging Headed Use a visible window and, if helpful, slow the automation so you can follow it.
Match behavior in branded Chrome or Edge Use the intended browser channel or binary Framework defaults can select a different headless implementation from the one you expect.
Reduce features or consider a headless shell Evaluate shell mode for the specific task It has documented behavior differences; do not assume it is interchangeable with modern Chrome Headless.

There is no universal speed or reliability winner established by the browser documentation. Choose according to observability, fidelity to the target browser, resource needs, and the framework, browser channel, and version in use.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why “headless” does not always mean the same browser

Chrome’s modern Headless and the older shell

Chrome for Developers says modern Chrome Headless shares the browser implementation with headful Chrome. Since Chrome 132.0.6793.0, the older headless mode is available as a separate chrome-headless-shell binary. The distinction matters if you are comparing results or reproducing a bug: record which binary and version ran, rather than noting only “headless Chrome.” See Chrome’s Headless mode documentation.

Playwright’s Chromium choices

Playwright documents that its default headless setup can use a separate Chromium headless shell, while headed operations use a regular Chromium build. Selecting the chromium channel opts into new headless mode. Branded Chrome and Edge can also behave differently from the default Chromium headless shell. Consult the current Playwright browser documentation when choosing a channel or diagnosing a difference.

Puppeteer’s choices

Current Puppeteer defaults to Headless mode. Set headless: false to launch headed Chrome; set headless: 'shell' to select the older headless shell. Puppeteer describes the shell as offering a performance tradeoff alongside behavior differences, but that does not establish that it will be faster or better for every workload. See Puppeteer’s headless modes guide.

Run and debug with Playwright

These examples use JavaScript and Chromium. Install Playwright and its browser first:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Run npm init -y in a new project directory.
  2. Run npm install playwright.
  3. Run npx playwright install chromium.
  4. Save one of the examples below as capture.js, then run it with node capture.js.

Default headless execution

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

Playwright runs browsers headlessly by default. The example opens a page, waits for its load event, saves a full-page screenshot, and closes the browser. Replace the example URL with the page you need to automate. The screenshot call is useful in unattended runs because it preserves visual output without opening a window.

Switch to headed execution

Set headless: false to see the browser while the same script runs:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

On a server or container with no graphical display, a visible browser may not be available. Use a suitable local desktop environment for interactive inspection, or keep the job headless and collect screenshots and logs as debugging evidence.

Slow the run to observe it

Playwright’s slowMo option adds a delay between operations, making a headed run easier to follow. The following example uses a 250-millisecond delay; that is an example setting, not a recommended universal value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false, slowMo: 250 });
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

For test-specific guidance, see Playwright’s debugging documentation.

Use Puppeteer when your project uses it

Puppeteer’s JavaScript API makes the mode choice at browser launch. Install the package with npm install puppeteer, save the selected example as capture.js, and run node capture.js.

Default headless mode

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

Visible browser window

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

Older headless shell

To explicitly use Puppeteer’s shell mode, launch with headless: 'shell':

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: 'shell' });
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'shot.png', fullPage: true });
  await browser.close();
})();

Use this mode only when its behavior and available capabilities suit your task. Compare results against the exact browser mode you intend to run, rather than assuming shell output represents every headless or headed browser. The mode details are documented in Puppeteer’s headless modes guide.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a website screenshot rather than a browser automation project, ScreenshotNeo provides a screenshot API and MCP server for developers. One GET request returns an image or PDF; its documented options cover full-page captures, selectors, viewport and device settings, and more. See the ScreenshotNeo API documentation.

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

Cookie banners, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free.

Troubleshoot mode and output problems

  • You set headless but see a different result from Chrome on your desktop. Check the framework, browser channel or binary, and version. Playwright’s default headless shell is not necessarily the same choice as branded Chrome or its chromium channel.
  • A headed launch fails in CI or a container. A visible window needs a graphical display. Run headless in an unattended environment, or arrange an appropriate display environment if visual interaction is essential.
  • A screenshot is blank or incomplete. Confirm that navigation reached the intended page and that capture occurs after the content you need has rendered. A screenshot records the page state at capture time; waiting for the load event alone may not indicate that every application-specific element is ready.
  • The older shell produces unexpected behavior. Verify whether your framework selected a shell or modern headless implementation. Compare with the intended target binary and consult the framework’s mode documentation.
  • A failure is hard to reproduce. Record the framework and version, browser channel or binary and version, headless setting, target URL, and relevant launch configuration. Use headed mode or Playwright’s slowMo when directly watching the interaction would help.

Performance, reliability, and reproducibility

Headless mode avoids displaying a browser window, which suits unattended work, but that fact alone does not prove a particular script will run faster. Puppeteer documents a performance tradeoff for the older shell, while also distinguishing its behavior from modern headless mode. Measure against your own pages and workload if performance determines the choice.

For consistent automation, pin or record the framework and browser version and select the channel or binary deliberately. A test result is meaningful only in relation to the implementation that produced it. When a headed local run and a headless CI run disagree, first compare those configurations before treating the difference as a general property of headless browsing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does headless Chrome behave the same as regular Chrome?

Modern Chrome Headless shares Chrome’s browser implementation with headful Chrome, but a framework may launch a different binary or the older headless shell. Check the selected channel and mode.

Can a headless browser take screenshots or make PDFs?

Yes. Headless execution can produce screenshots and PDFs; Chrome also documents remote debugging and virtual screen configuration.

Which mode should I use for browser tests?

Use headless for unattended runs when its implementation matches the target; use headed mode when seeing the interactions helps you diagnose a test.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.