Chrome Headless Flags: What They Do for Screenshots

Chrome flags are command-line switches set at launch. The headless flags that matter for screenshots, what Puppeteer and Playwright add, and tested traps.

By Simon Chiu · Updated

Chrome flags (also called switches) are command-line arguments such as --headless or --window-size=1280,800 that change how the Chrome process behaves for its whole lifetime, set once when the browser starts.

They are different from per-page settings. A flag applies to every tab in that browser process, and you cannot change it without a restart. This entry is part of the screenshot glossary.

What they are in plain terms

When Puppeteer or Playwright "launches Chrome", it runs the Chrome executable with a long list of flags. Some switch off background work you do not want in automation (updates, sync, the first-run screen). Some open the control channel, the Chrome DevTools Protocol. And you can add your own.

We printed the real command line from both libraries. Puppeteer 24.43.1 adds 33 flags before yours. Playwright 1.64.1 started its browser with 46. Two of them matter most for screenshots:

Library Binary it starts by default Headless flag Sandbox
Puppeteer 24 Chrome for Testing (chrome) --headless=new On (no --no-sandbox)
Playwright 1.64 chrome-headless-shell --headless Off (--no-sandbox added)

So the "same" headless screenshot runs on different binaries with different security settings, depending on the library. See chrome-headless-shell and the Chromium sandbox for what that means.

Where flags sit

flowchart TB
  A["Process flags<br/>--headless, --window-size, --force-device-scale-factor, --no-sandbox"] --> B[Browser process]
  B --> C["Browser context<br/>cookies, permissions, proxy"]
  C --> D["Page settings via CDP<br/>viewport, locale, media, user agent"]
  D --> E[Screenshot]

A flag is the outermost layer. Anything a library can set per page (viewport, locale, color scheme) is the better choice, because one browser can then serve many jobs with different settings.

Flags that affect screenshots

Flag Effect Per-page alternative
--headless / --headless=new Run without a window none
--window-size=1280,800 Initial window size page.setViewport / viewport option
--force-device-scale-factor=2 Retina-style 2x pixels deviceScaleFactor
--hide-scrollbars No scrollbar in captures Puppeteer adds it by default
--force-color-profile=srgb Stable colors across machines Puppeteer adds it by default
--disable-dev-shm-usage Use /tmp instead of a small /dev/shm in Docker none
--no-sandbox Turn off process isolation Avoid; see the sandbox entry
--remote-debugging-port=9222 Open the CDP port none
--lang=de-DE UI language Accept-Language header and locale emulation

Setting flags in Puppeteer, Playwright and RenderScreenshot

Puppeteer takes extra flags in args, and you can read back what Chrome really received:

import puppeteer from 'puppeteer';

console.log(`${puppeteer.defaultArgs({ headless: true }).length} default flags`);

const browser = await puppeteer.launch({
  args: ['--window-size=1280,800', '--force-device-scale-factor=2', '--lang=de-DE'],
});
try {
  const spawned = browser.process().spawnargs.slice(1);
  console.log(spawned.filter((f) => /window-size|scale-factor|lang|headless/.test(f)));

  const page = await browser.newPage();
  await page.setViewport(null); // keep the window size instead of Puppeteer's 800x600 default
  await page.goto('https://example.com');
  console.log(await page.evaluate(() => ({
    dpr: devicePixelRatio,
    width: innerWidth,
    languages: navigator.languages,
  })));
} finally {
  await browser.close();
}

Output: 33 default flags, then { dpr: 2, width: 1280, languages: [ 'en-US' ] }. The scale and window flags worked. --lang=de-DE did not change navigator.languages in headless mode on our machine. For localized captures, set the locale per page instead.

Playwright has the same args option. To see the full command line, start a browser server, which exposes the child process:

import { chromium } from 'playwright';

const server = await chromium.launchServer({ args: ['--force-device-scale-factor=2'] });
try {
  const spawned = server.process().spawnargs.slice(1);
  console.log(`${spawned.length} flags`);
  console.log(spawned.filter((f) => /headless|sandbox|scale-factor/.test(f)));
} finally {
  await server.close();
}

Output: 46 flags and [ '--headless', '--no-sandbox', '--force-device-scale-factor=2' ]. For scale, locale and viewport, Playwright's newContext({ deviceScaleFactor, locale, viewport }) is the cleaner route.

With RenderScreenshot you do not pass flags. Each request gets a fresh browser session, and the per-capture settings are request parameters:

curl -G https://api.renderscreenshot.com/v1/screenshot \
  -H "Authorization: Bearer $RS_API_KEY" \
  --data-urlencode "url=https://example.com" \
  -d width=1280 -d height=800 -d scale=2 -d locale=de-DE \
  --output [email protected]

scale maps to viewport.scale and locale to browser.locale, which also sets the Accept-Language header. See the viewport and browser options.

Tested on 2026-10-15 on macOS 27 (arm64) with Node 22.18.0, [email protected] (Chrome 148.0.7778.97) and [email protected] (chrome-headless-shell 156.0.8078.4). The curl request was not run for this page.

Common mistakes

  • Copying flag lists from old blog posts. --disable-gpu was a workaround for early headless builds. --single-process and --no-zygote make Chrome less stable. Add a flag only when you can name the problem it fixes.
  • Using flags for per-job settings. Locale, viewport and scale belong on the page or context, so one browser can serve every job. See scaling Puppeteer screenshots.
  • Adding --no-sandbox by reflex. It is often needed only because Chrome runs as root in a container. Fix the user instead.
  • Forgetting that flags change between versions. Switches are not a stable API. Re-check them when you upgrade the browser.

To capture pages without managing a Chrome command line, create a free account.

Frequently asked questions

Are Chrome flags the same as chrome://flags?
No. chrome://flags is a settings page for experimental features in a normal browser profile. Command-line flags (switches) are passed when the process starts, and that is what automation tools use. Some features can be set both ways, for example with --enable-features.
Is there an official list of all Chrome flags?
There is no complete, stable official list. Switches are defined in Chromium's source and change between versions. Peter Beverloo's community-maintained list is the usual reference, but test each flag on the Chrome version you ship.
Does --headless=new still work?
Yes. In current Chrome, --headless and --headless=new both start the new headless mode in the chrome binary. The old headless mode is a separate binary, chrome-headless-shell.

Related in this topic

Try RenderScreenshot free

150 free credits every month, no credit card required.