Puppeteer Chrome Headless Shell Settings Explained
Learn how Puppeteer’s Headless Shell settings control browser downloads and runtime behavior, when to use shell mode, and how to troubleshoot common issues.
In Puppeteer v25.12.0, set headless: 'shell' in puppeteer.launch() to launch the separate chrome-headless-shell binary. Set headless: true to use Chrome’s newer headless mode. Shell can be more performant for automation that does not need the complete Chrome feature set, but its behavior is not identical to regular Chrome. Check the version installed in your project before copying version-specific assumptions.
There are two different groups of Headless Shell settings: installation configuration controls which shell binary Puppeteer downloads, while launch options control how the browser runs. The settings are not interchangeable.
Choose between new headless Chrome and Headless Shell
| Setting | Browser implementation | When to consider it |
|---|---|---|
headless: true |
Chrome’s newer headless mode | When your automation needs behavior closer to current Chrome. |
headless: 'shell' |
The separate chrome-headless-shell binary, formerly called old headless |
When the task does not need the full Chrome feature set and you want to evaluate Shell for the workload. |
headless: false |
Headful Chrome | When you need to observe the browser or use behavior that requires a visible browser window. |
Puppeteer characterizes Shell as currently more performant for automation that does not require the complete Chrome feature set. The documentation provides no benchmark number. Measure your own workload, and validate the browser features and page behavior you rely on before switching modes.
Run a complete Headless Shell example
Install Puppeteer in a project with Node.js. The puppeteer package downloads a compatible browser during installation when its install script runs.
npm install puppeteer
Save the following as capture.cjs and run it with node capture.cjs. It launches Headless Shell, navigates to a page, waits for the document to load, and saves a screenshot.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'shell',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 30_000,
});
await page.screenshot({ path: 'example.png', fullPage: true });
} finally {
await browser.close();
}
})().catch(error => {
console.error(error);
process.exitCode = 1;
});
If you need to pass a browser command-line flag, add it to args. For example, Headless Shell requires --enable-gpu to enable GPU acceleration in headless mode. Use that flag only if GPU acceleration is wanted and available in the runtime environment.
const browser = await puppeteer.launch({
headless: 'shell',
args: ['--enable-gpu'],
});
Understand install-time Chrome Headless Shell settings
The "chrome-headless-shell" section in Puppeteer configuration controls acquisition of the Shell binary. It does not select Shell for a particular browser launch; that is the job of headless: 'shell'.
| Setting | Purpose | Environment override |
|---|---|---|
downloadBaseUrl |
Sets the URL prefix used to download the browser. It must include a protocol and must not end with a trailing slash. | PUPPETEER_CHROME_HEADLESS_SHELL_DOWNLOAD_BASE_URL |
skipDownload |
Prevents downloading the Shell binary during installation. | PUPPETEER_CHROME_HEADLESS_SHELL_SKIP_DOWNLOAD or PUPPETEER_SKIP_CHROME_HEADLESS_SHELL_DOWNLOAD |
version |
Selects the Shell version. By default, Puppeteer uses the version pinned for that Puppeteer release. | PUPPETEER_CHROME_HEADLESS_SHELL_VERSION |
For example, a project can set the configuration in a .puppeteerrc.cjs file:
/** @type {import('puppeteer').Configuration} */
module.exports = {
chromeHeadlessShell: {
skipDownload: false,
// downloadBaseUrl: 'https://your-browser-mirror.example',
// version: '154.0.8037.57',
},
};
The version shown is an example of a version string, not a permanent recommendation. Use the version compatible with your installed Puppeteer release and your browser distribution. Keep the property names and supported configuration shape aligned with the documentation for the version in your package lock.
Configure runtime launch options
These options are passed to puppeteer.launch(); they affect a running browser process rather than installation.
| Option | What it controls | Practical guidance |
|---|---|---|
headless |
Selects headful Chrome, new headless Chrome, or Headless Shell. | Use 'shell' specifically for Shell; true selects new headless mode. |
args |
Additional command-line arguments passed to Chrome. | Add only flags required by the workload. Shell GPU acceleration requires --enable-gpu. |
executablePath |
Uses a specific browser executable. | Useful when managing the browser yourself, but an external executable is not guaranteed to work with Puppeteer. |
channel |
Selects an installed Chrome release channel. | Use when intentionally targeting an installed channel; check compatibility with the Puppeteer release. |
ignoreDefaultArgs |
Removes all Puppeteer default arguments or filters selected ones. | Use carefully. Removing defaults can change browser behavior or break assumptions Puppeteer makes. |
Puppeteer guarantees compatibility with its bundled browser, not arbitrary externally managed executables. If you select a custom executable or channel, verify that the browser version and behavior work with your Puppeteer version.
Install and version the browser reliably
- Check the Puppeteer version actually installed in the project, including the lockfile and deployment image.
- For the
puppeteerpackage, let its install process download the browser versions associated with that release unless you have a deliberate browser management strategy. - Confirm that package installation scripts are allowed to run in CI and container builds. If a package manager suppresses install scripts, the browser download may not happen.
- If using
puppeteer-core, provide your own browser through an executable path or channel;puppeteer-coredoes not download a browser. - Keep Puppeteer and the browser binary version aligned, and validate your capture against the actual production environment.
For Puppeteer v25.12.0, the documented supported-browser mapping is Chrome for Testing 154.0.8037.57. This is a release-specific mapping; consult the supported browsers page for the Puppeteer version you use rather than pinning this number indefinitely.
Screen configuration and display behavior
Puppeteer documents --screen-info for headless display layouts. The flag is available only in headless mode. Headful Chrome uses the platform’s physical screens. Runtime screen management is also exposed through the Chrome DevTools Protocol methods Browser.addScreen, Browser.removeScreen, and Browser.screens. These are specialized controls; most screenshot scripts can set a viewport through Puppeteer’s page API without changing the browser’s screen layout.
Troubleshoot common Headless Shell problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Launch fails because the Shell executable cannot be found. | The Shell download was skipped, or install scripts did not run. | Check the skipDownload settings and environment overrides, then allow Puppeteer’s install step to run or manage the executable explicitly. |
puppeteer-core cannot launch a browser. |
puppeteer-core does not download one. |
Set executablePath or channel to a browser available in the environment, and verify compatibility. |
| A custom Chrome path launches inconsistently or errors. | The external browser may not match Puppeteer’s expected version or behavior. | Prefer the bundled browser, or align the external binary with the supported-browser mapping for the installed Puppeteer version. |
| GPU acceleration is unavailable in Shell. | Headless Shell requires the GPU flag to enable GPU acceleration in headless mode, or the environment lacks GPU support. | Add args: ['--enable-gpu'] when GPU acceleration is desired and supported; otherwise run without expecting GPU acceleration. |
| Chrome exits or fails on Linux with a sandbox-related error. | The process environment may not provide the sandbox requirements Chrome expects. | Configure a usable Chrome sandbox. Puppeteer strongly discourages disabling it because it protects the host from untrusted web content. Use --no-sandbox only when the opened content is absolutely trusted and there is no suitable sandbox configuration. |
| Captures differ from regular Chrome. | Headless Shell is a distinct implementation and does not match regular Chrome completely. | Reproduce the page in headless: true or headful Chrome, then check whether the page relies on a feature that differs in Shell. |
| The browser downloads on a developer machine but not in CI. | Install scripts may be blocked, or the CI image may not contain a browser. | Inspect package-manager install-script policy and make browser installation an explicit, reproducible build step. |
| A configured browser download URL is rejected. | The URL may omit its protocol or end with a slash. | Set downloadBaseUrl to a protocol-qualified prefix without a trailing slash. |
Performance, reliability, and cost considerations
Shell’s performance advantage is qualitative in Puppeteer’s documentation, not a published guarantee or fixed speedup. Compare total job time and correctness on representative pages, including scripts, fonts, images, and any browser APIs your workflow uses. A faster launch is not useful if pages render differently or the automation needs a feature Shell does not provide.
For reliability, pin dependencies, install the browser reproducibly, set explicit navigation timeouts, and close the browser in a finally block. Revalidate after upgrading Puppeteer because the bundled browser mapping and option surfaces can change. On shared or production systems, keep Chrome’s sandbox enabled where possible.
Self-hosted Puppeteer has no per-screenshot API fee, but browser compute, memory, storage, bandwidth, and maintenance are still operational costs. Account for retries and concurrency when sizing workers, and avoid assuming that failed navigation or bot checks are free in your own infrastructure.
Or skip the browser setup
If your goal is to capture a page rather than manage a browser binary and runtime, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. The API docs are at screenshotneo.com/docs.
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)
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}`);
Cookie banners are accepted like a visitor and removed, along with known newsletter popups and chat widgets, before the screenshot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. An MCP server gives AI agents tools to take screenshots, inspect page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Start with 1,000 free screenshots a month, no card required.
FAQ
Is headless: 'shell' the same as headless: true?
No. Shell launches the separate chrome-headless-shell binary; true selects Chrome’s newer headless mode.
Which setting changes the Headless Shell download version?
The install-time chrome-headless-shell.version configuration field, which can also be overridden with PUPPETEER_CHROME_HEADLESS_SHELL_VERSION.
Does Headless Shell always run faster?
No universal speedup is documented. Puppeteer describes it as more performant for automation that does not need the complete Chrome feature set; benchmark your own task and check compatibility.
Should I add --no-sandbox to make deployment easier?
No. Configure Chrome’s sandbox where possible. Puppeteer strongly discourages disabling it and documents that workaround only for absolutely trusted content.


