ScreenshotNeo

BlogHow-to

How to Skip Puppeteer’s Browser Download During Installation

Stop Puppeteer from downloading Chrome during install with an environment variable or project config, then connect to a browser you manage.

By the ScreenshotNeo team1 October 20267 min read

Set PUPPETEER_SKIP_DOWNLOAD=true before installing puppeteer.

PUPPETEER_SKIP_DOWNLOAD=true npm install puppeteer

This prevents Puppeteer’s installation hook from downloading a browser. It does not install or provide a browser for runtime. If your program launches a local browser, install one separately and pass its executable path or channel. If you connect to a remote browser or manage browsers yourself, use puppeteer-core. See the official Puppeteer installation guide and configuration reference.

Choose the right way to skip the download

Method Best for Scope
PUPPETEER_SKIP_DOWNLOAD=true One shell command, CI job, or deployment environment That install process and its environment
skipDownload: true A setting that should live with the project Project configuration
chrome.skipDownload: true Skipping Chrome while keeping other browser settings independent Chrome-specific configuration
puppeteer-core Remote or self-managed browsers No Puppeteer browser download; configuration files and Puppeteer environment variables are ignored

Option 1: use the environment variable

npm

PUPPETEER_SKIP_DOWNLOAD=true npm install puppeteer

pnpm

PUPPETEER_SKIP_DOWNLOAD=true pnpm add puppeteer

Yarn

PUPPETEER_SKIP_DOWNLOAD=true yarn add puppeteer

Set the variable in the same environment where the package manager runs, before the install script starts. On Windows PowerShell:

$env:PUPPETEER_SKIP_DOWNLOAD = "true"
npm install puppeteer

On Windows Command Prompt:

set PUPPETEER_SKIP_DOWNLOAD=true && npm install puppeteer

For a CI job, define the variable in that job’s environment rather than relying on a developer’s local shell profile.

Option 2: save the setting in project configuration

Puppeteer supports project configuration files such as .puppeteerrc.json, .puppeteerrc.js, puppeteer.config.js, and a puppeteer property in package.json. A JSON configuration is portable:

{
  "skipDownload": true
}

Example .puppeteerrc.js:

/** @type {import('puppeteer').Configuration} */
module.exports = {
  skipDownload: true,
};

Example in package.json:

{
  "name": "capture-worker",
  "puppeteer": {
    "skipDownload": true
  }
}

Environment variables take precedence when applicable. After changing download options, rerun the relevant installation step. Puppeteer documents npx puppeteer browsers install for installing browsers according to the current configuration.

Skip only Chrome

The global setting applies to browser downloads generally. If you need browser-specific control, use Chrome’s setting:

/** @type {import('puppeteer').Configuration} */
module.exports = {
  chrome: {
    skipDownload: true,
  },
};

The corresponding environment override is:

PUPPETEER_CHROME_SKIP_DOWNLOAD=true npm install puppeteer

Use the global variable when every Puppeteer-managed browser download should be suppressed; use the browser-specific setting when your project needs different behavior by browser.

What changes at runtime

Skipping installation only removes the automatic download. A normal puppeteer launch still needs a browser executable available on the machine.

Launch a system browser by executable path

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  executablePath: process.env.CHROME_PATH,
  headless: true,
});

const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
console.log(await page.title());
await browser.close();

Set CHROME_PATH to the browser installed by your operating system, container image, or deployment platform. A channel can be used instead when Puppeteer should locate a standard installed browser channel:

const browser = await puppeteer.launch({
  channel: 'chrome',
  headless: true,
});

Confirm that the browser version is supported by your Puppeteer release. Puppeteer publishes a version mapping in its supported browsers page; do not assume any arbitrary system Chrome is interchangeable.

Use a remote browser with puppeteer-core

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: process.env.BROWSER_WS_ENDPOINT,
});

const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();

puppeteer-core is intended for users connecting to a remote browser or managing browsers themselves. Its configuration files and Puppeteer environment variables are ignored, and installing it does not download Chrome.

Complete installation examples

Local browser supplied by your image or host

mkdir capture-worker
cd capture-worker
npm init -y
PUPPETEER_SKIP_DOWNLOAD=true npm install puppeteer
import puppeteer from 'puppeteer';

const executablePath = process.env.CHROME_PATH;
if (!executablePath) {
  throw new Error('Set CHROME_PATH to an installed Chrome or Chromium executable');
}

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

Remote browser service

npm init -y
npm install puppeteer-core
import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: process.env.BROWSER_WS_ENDPOINT,
});
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.screenshot({ path: 'example.png' });
await browser.close();

Package-manager scripts and locked-down CI

Some package managers or CI policies block dependency install scripts. That can also prevent Puppeteer’s automatic browser download, even when you did not set a skip variable. If the application needs a local browser, either allow Puppeteer’s install script or install the browser explicitly with Puppeteer’s browser installer, following the official installation instructions.

Keep the install policy and runtime setup together: a reproducible build should document where the browser comes from, which executable path is used, and how the version is checked.

Docker and deployment checklist

  • Set PUPPETEER_SKIP_DOWNLOAD=true during dependency installation.
  • Install a supported Chrome or Chromium package in the image, or provide a remote browser endpoint.
  • Set CHROME_PATH (or use a supported channel) when launching locally.
  • Run the browser with the sandbox settings required by your container runtime; follow your platform’s security policy.
  • Cache the package manager directory, not an accidentally downloaded browser, when the goal is to reduce build traffic.
  • Verify the installed Puppeteer release against its browser support matrix.

Performance, reliability, and cost considerations

Build performance

Skipping the download reduces install time and network use. Puppeteer’s documentation lists approximate automatic-download sizes of about 170 MB on macOS, 282 MB on Linux, and 280 MB on Windows. Treat those as platform-specific estimates, not guaranteed transfer sizes.

Runtime reliability

The trade-off is operational responsibility. A missing executable, incompatible browser revision, missing shared library, or blocked sandbox can turn a successful install into a runtime failure. Pin the browser source used by your image or host and check the Puppeteer support matrix for the release you deploy.

Cost

The skipped download does not remove browser compute, storage, or network costs elsewhere. A self-managed browser still consumes resources; a remote browser usually charges according to its provider’s plan. Measure cold-start time and concurrency in the environment where the worker runs.

Common errors and fixes

Error or symptom Cause Fix
Could not find Chrome or a missing executable error The download was skipped and no browser was supplied Install a supported browser and set executablePath or channel, or connect with puppeteer-core.
The browser downloads anyway The variable was set after installation, misspelled, or applied to a different package-manager process Set PUPPETEER_SKIP_DOWNLOAD=true before install and rerun it. Check the effective CI environment.
Configuration has no effect The file name, location, or property is wrong Use a supported project file and the exact skipDownload property. Remember that puppeteer-core ignores these files.
Only Chrome should be skipped, but another browser is affected A global setting was used Use the browser-specific setting such as chrome.skipDownload or PUPPETEER_CHROME_SKIP_DOWNLOAD.
Install succeeds but launch fails in CI Install scripts were blocked or the image lacks browser dependencies Allow the install script or install the browser explicitly; add required OS libraries and verify the executable path.
Protocol or launch errors after a browser upgrade The browser and Puppeteer versions are outside the supported mapping Check the release’s supported-browser table and align the versions.
Environment setting appears ignored A stale installation or cached dependency was reused Rerun the installation step with the setting present and invalidate the relevant package-manager cache.

How to verify the setting

  1. Remove the existing installation or use a clean workspace.
  2. Run the package-manager command with PUPPETEER_SKIP_DOWNLOAD=true.
  3. Inspect the install log to confirm no browser archive was fetched.
  4. Run a launch smoke test with an explicit executablePath, channel, or remote endpoint.
  5. Record the Puppeteer and browser versions in build logs.

Or skip the browser setup

If your goal is simply to produce website screenshots, ScreenshotNeo provides a one-request screenshot API and MCP server, so your application does not need to install or manage Puppeteer browsers.

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}`);

See the ScreenshotNeo API documentation for request options. Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status with X-Page-Verdict and X-Billed headers. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account.

FAQ

Does skipping the download make Puppeteer smaller?

It removes the browser archive from installation. The Puppeteer package and its Node dependencies still install.

Can I use skipDownload with puppeteer-core?

No. puppeteer-core ignores Puppeteer configuration files and environment variables because it is designed for self-managed or remote browsers.

Do I need to reinstall after adding the variable?

Yes. Download options are evaluated during installation, so rerun the install step after changing the variable or configuration.

Which browser version should I install?

Use the supported-browser mapping for your exact Puppeteer release and target platform. Compatibility is release-specific.

Is a system Chrome always compatible?

No. A system browser can work when its version and platform are supported, but verify the mapping instead of assuming interchangeability.