How to Choose the Default Browser in Puppeteer
Puppeteer launches Chrome by default. Learn how to set a persistent browser default, choose a browser for one launch, and use an installed Chrome executable safely.
Puppeteer launches Chrome by default. To change the choice for a single launch, pass browser to puppeteer.launch(). For the puppeteer package, set the persistent default with the defaultBrowser configuration option or the PUPPETEER_BROWSER environment variable. Use channel to select a regular installed Chrome release, or executablePath to point at a specific browser executable.
“Default browser” here means the browser Puppeteer launches. It does not change your operating system’s default browser for opening links.
Which browser does Puppeteer use by default?
The current Puppeteer Configuration API lists chrome as the default for defaultBrowser, and the LaunchOptions API likewise lists Chrome as the default for a launch. Installing puppeteer downloads Chrome for Testing for Puppeteer to use. Puppeteer says it is guaranteed to work with its bundled browser; other browser versions are not guaranteed. For the most directly supported setup, keep the bundled browser unless your environment calls for a different one.
Source: Puppeteer Configuration API, LaunchOptions API, and installation guide.
Choose the right configuration method
| Need | Use | Applies to |
|---|---|---|
| Keep the bundled, compatibility-focused browser | Omit browser overrides | puppeteer |
| Set a package-wide default browser | defaultBrowser in Puppeteer configuration |
puppeteer; configuration is ignored by puppeteer-core |
| Override the configured browser in the environment | PUPPETEER_BROWSER |
puppeteer |
| Select a browser for one script or job | browser in launch() |
That launch |
| Use a regular Chrome installation | channel |
That launch; resolves Chrome from a known system location |
| Use a browser at a managed or custom path | executablePath |
That launch |
| Let another system manage installation or a remote browser | puppeteer-core with an explicit connection or launch configuration |
Your browser-management setup |
The documented Chrome channel option is for Chrome release channels. It does not select arbitrary browser brands. The browser-management guide says system-browser launching is limited to Chrome and Chromium. Treat Firefox as a separately configured or downloaded browser rather than assuming Chrome channel settings apply to it.
Set a persistent default with Puppeteer configuration
For a project using puppeteer, put the browser choice in a Puppeteer configuration file. The configuration guide documents configuration files and environment variables for persistent defaults. Its current “Next” guide describes multi-browser download configuration starting with Puppeteer v23.0.0; check the documentation for your installed version before relying on version-specific behavior.
// .puppeteerrc.cjs
module.exports = {
defaultBrowser: 'chrome',
};
Replace chrome with another supported browser value only if that browser is installed and supported by your Puppeteer setup. The configuration API types this setting as SupportedBrowser. Then run a minimal launch to confirm that your installed Puppeteer version recognizes the configuration.
// check-browser.cjs
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
console.log(await browser.version());
await browser.close();
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
For an environment-specific default, set PUPPETEER_BROWSER before starting Node:
# macOS or Linux
PUPPETEER_BROWSER=chrome node check-browser.cjs
# PowerShell
$env:PUPPETEER_BROWSER = 'chrome'
node .\check-browser.cjs
The configuration reference says PUPPETEER_BROWSER overrides the configuration value. When you need a reproducible launch across machines, set the choice explicitly in your deployment configuration and verify the resulting browser version.
Select the browser for one launch
Pass browser in the launch options when a particular script should make its choice explicit. This avoids relying on an environment or project default for that call.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
browser: 'chrome',
headless: true,
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Use a browser value supported by the installed Puppeteer version and available in the environment. The launch API’s documented default is Chrome. Do not infer that a browser choice by itself installs that browser; package installation and browser management are separate concerns.
Use installed Chrome with a channel
Set channel when you want Puppeteer to find a regular Chrome installation in a known system location. For example:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
channel: 'chrome',
headless: true,
});
try {
console.log(await browser.version());
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Use a channel name documented by the Puppeteer version you installed. This option is useful when Chrome is installed conventionally. If the browser lives somewhere nonstandard, use executablePath instead. An installed browser may have a version that Puppeteer does not guarantee to support.
Point to a specific executable
Use executablePath when your container, CI image, or deployment system manages the browser at an exact path. Puppeteer recommends setting browser alongside the path because the browser otherwise defaults to Chrome.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
browser: 'chrome',
executablePath: process.env.CHROME_PATH,
headless: true,
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Set CHROME_PATH to a path that exists in the runtime and is executable by the process. Puppeteer also documents PUPPETEER_EXECUTABLE_PATH as an environment override for the executable path configuration. Do not assume this makes an arbitrary browser binary compatible: Puppeteer guarantees compatibility with its bundled browser, and using another browser or version is your responsibility.
Know when to use puppeteer-core
The puppeteer package downloads a browser and supplies end-user defaults. puppeteer-core does not download Chrome and does not read Puppeteer configuration files or environment configuration. Choose it when another component manages the browser or when you connect to a remote browser. For a locally managed browser, supply an executable path or channel:
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
browser: 'chrome',
executablePath: process.env.CHROME_PATH,
headless: true,
});
try {
console.log(await browser.version());
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
For a remote browser, use the connection mechanism supplied by that browser provider or manager; a local executablePath is not a remote connection URL. See the installation guide and PuppeteerNode API.
Installation and deployment checklist
- Decide whether you need Puppeteer’s bundled Chrome for Testing, a regular installed Chrome, or a precisely managed executable.
- Use
puppeteerwhen you want Puppeteer to download its browser. Usepuppeteer-corewhen your application or infrastructure manages the browser. - For a persistent default with
puppeteer, configuredefaultBrowseror setPUPPETEER_BROWSER. For a one-off choice, setbrowserat launch. - For standard-location Chrome, configure
channel. For a nonstandard location, configureexecutablePathand explicitly setbrowser. - In CI or containers, confirm the browser binary is present, executable, and available to the same user that runs Node.
- Log or inspect
browser.version()during diagnosis, and validate upgrades in your target environment.
Puppeteer’s installation guide notes that modern package managers may block install scripts. If the browser download did not run during installation, follow the guide’s browser-install instructions for your installed version. The default browser cache location is documented as $HOME/.cache/puppeteer beginning with Puppeteer v19; cache paths and installation behavior can vary by version and environment.
Performance, reliability, and cost
Browser selection affects what your process must install and maintain. The bundled browser adds a download and cache, while puppeteer-core avoids that managed download but requires your deployment to provide a compatible browser or remote connection. A system-installed browser can fit an existing image or browser-management workflow, but you must account for version changes and test it yourself.
For reliability, prefer the bundled browser when you want Puppeteer’s documented compatibility guarantee. Pin and validate your browser environment when using an external executable. For performance, browser startup and page loading are generally the operational costs to measure in your own workload; the reviewed Puppeteer sources provide no comparative startup benchmark, so do not assume one selection is faster for every deployment.
Cost includes browser storage, image or container size, CI time, and any remote browser service your architecture uses. The Puppeteer documentation does not specify a universal cost per capture or runtime; estimate it from your deployment and usage.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Puppeteer still launches Chrome | The desired choice was not set for this package or launch, or configuration is being used with puppeteer-core. |
For puppeteer, check defaultBrowser and PUPPETEER_BROWSER. For a single launch, pass browser. Remember that puppeteer-core ignores configuration files and environment configuration. |
| Browser executable not found | The install download was skipped, the channel cannot find a standard installation, or the configured path is wrong in the runtime. | Install the browser using the instructions for your Puppeteer version, check the effective path inside the container or CI job, or use a valid channel for a standard Chrome install. |
| Permission denied when launching | The process user cannot execute or access the browser binary or its parent directories. | Check ownership and executable permissions in the runtime image; run the process as the expected user and ensure the browser path is mounted and accessible. |
| Launch fails after a browser upgrade | The external browser version may not match the Puppeteer version’s expected protocol or runtime behavior. | Use Puppeteer’s bundled browser for the compatibility guarantee, or pin and validate your externally managed browser with the installed Puppeteer release. |
| Configuration file appears ignored | The package is puppeteer-core, the file is not in a supported location/name, or the installed version differs from the guide. |
Confirm the package and version, consult that version’s configuration guide, and use explicit launch options when you need predictable behavior. |
| Environment setting has no effect | The variable was set in a different shell or after the Node process started, or the package is puppeteer-core. |
Set it in the process environment before starting Node. Use puppeteer for environment-based Puppeteer configuration, or provide launch options directly. |
| Works locally but fails in CI | The local browser path, cache, permissions, or install scripts differ from CI. | Install or provide the browser in the CI image, verify the path as the CI user, and print browser.version() after launch during diagnosis. |
Or skip the browser setup
If your goal is to capture a website rather than control a browser process, ScreenshotNeo provides a website screenshot API and MCP server. Its API accepts one GET request with a URL and returns a PNG, JPEG, WebP, or PDF. 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
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, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing status. An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.
FAQ
Does changing Puppeteer’s browser change my system default browser?
No. It changes the browser Puppeteer launches for automation, not the operating system’s default app for web links.
Can I use any browser with channel?
No. The documented channel setting resolves a Chrome release channel. For a specific managed binary, use executablePath and check compatibility.
Should I set the browser in configuration or at launch?
Use configuration for a package default in puppeteer; use the launch option when a particular script needs an explicit choice. Explicit launch settings help make that script’s intent clear.
Is puppeteer-core the same as puppeteer without a browser option?
No. puppeteer-core does not download a browser and ignores Puppeteer configuration files and environment configuration. Your application must manage or connect to the browser.


