Puppeteer Browser Management: Default Provider
Learn what Puppeteer’s default browser and default provider mean, how to configure browser downloads, and when a custom provider makes sense.
Puppeteer’s defaultBrowser setting selects which browser Puppeteer uses; it currently defaults to Chrome. The default provider is different: it is the browser-download source used by @puppeteer/browsers. If you configure custom providers, Puppeteer automatically adds its default provider as the final fallback.
For most projects, use Puppeteer’s default browser binary and provider. That is the compatibility-assured path. Consider a custom provider only when you need control over where browser archives come from or which build is installed, and can take responsibility for version compatibility and testing.
1. Browser selection and download provider are different settings
| Term | What it controls | Default behavior |
|---|---|---|
defaultBrowser |
Which browser Puppeteer uses | Chrome |
| Default provider | Where the browser installer looks for a browser binary | Automatically added as the final fallback after custom providers |
Changing defaultBrowser does not select a custom download provider. Conversely, adding a provider changes the installer’s source chain; it does not by itself change the browser choice in Puppeteer configuration. The [configuration reference](https://pptr.dev/api/puppeteer.configuration) describes defaultBrowser as the browser Puppeteer should use. The [InstallOptions API](https://pptr.dev/browsers-api/browsers.installoptions) documents the provider fallback behavior.
2. What Puppeteer installs by default
Puppeteer downloads a browser version intended to work with its API. Its managed Chrome distribution is Chrome for Testing. Starting with Puppeteer v20, Chrome for Testing replaced Chromium as the downloaded and supported Chrome build. Exact browser versions change with Puppeteer releases, so use the supported-browser information for the version in your project rather than copying a version number from an older guide. See the [supported browsers table](https://pptr.dev/supported-browsers).
The default browser and the downloaded browser are related, but browser selection, binary installation, executable path, and download source are separate pieces of configuration.
3. Configure the browser Puppeteer uses
For the regular puppeteer package, set defaultBrowser in Puppeteer configuration or use the PUPPETEER_BROWSER environment variable. Environment values override applicable configuration-file values. Follow the [configuration guide](https://pptr.dev/guides/configuration) for the accepted file formats and supported browser names for your installed release.
// .puppeteerrc.cjs
module.exports = {
defaultBrowser: 'chrome',
};
To select another supported browser, use its documented name, for example firefox, if that browser is supported by your Puppeteer release:
// .puppeteerrc.cjs
module.exports = {
defaultBrowser: 'firefox',
};
Or set the environment variable for a single process:
PUPPETEER_BROWSER=firefox node app.js
The selected browser must also be installed if your setup skips automatic downloads. If you need to point at a specific existing executable, provide its path when launching Puppeteer:
const browser = await puppeteer.launch({
executablePath: '/path/to/browser',
headless: true,
});
Use an executable build compatible with the Puppeteer version and features your application depends on. For puppeteer-core, configuration files and Puppeteer environment configuration are ignored; provide browser setup explicitly, including the executable or connection settings required by your environment.
4. Manage browser downloads and cache
Browser choice does not determine whether installation downloads a browser. Puppeteer configuration also supports download controls, including skipDownload and browser-specific settings. If you change download configuration, run the documented browser installation command so the configured binary is present:
npx puppeteer browsers install
Inspect the [configuration guide](https://pptr.dev/guides/configuration) and [browser management guide](https://pptr.dev/guides/browser-management) for options supported by your installed version. The default browser cache location is ~/.cache/puppeteer for Puppeteer v19 and later. In containers and CI, make sure the install step and runtime use compatible cache paths and permissions.
- Choose the browser in configuration or with
PUPPETEER_BROWSER. - Decide whether Puppeteer should download it during installation.
- If downloads are skipped or package-manager install scripts are blocked, install the browser deliberately with the Puppeteer browser command or provide an existing executable.
- Keep the Puppeteer version and browser build consistent between development, CI, and production.
- Launch a small smoke-test page in the target environment before depending on the browser in a larger workflow.
5. Use a custom provider
The @puppeteer/browsers install API accepts optional providers. You can chain multiple providers in order; Puppeteer adds its default provider last as a fallback. The provider interface is an advanced integration point, and custom providers are not officially supported by Puppeteer.
A custom provider can be useful when an organization mirrors browser archives, controls artifact distribution, or needs a specific browser build source. It also transfers operational responsibility to you:
- Confirm that the provider serves archives in the format the installer expects.
- Verify that the browser build matches the Puppeteer release and required features.
- Test installation and launch on every target operating system and architecture.
- Keep versions pinned consistently across developer machines, CI, and deployment images.
- Plan how failed downloads, unavailable mirrors, and browser updates will be handled.
Puppeteer tests and guarantees compatibility for its default binaries, not custom-provider binaries. Treat the default fallback as a recovery path for source lookup, not as a guarantee that an arbitrary custom binary is compatible. See the [install API](https://pptr.dev/browsers-api/browsers.installoptions) for provider behavior and support limitations.
6. Launch, connect, and isolate browser work
The provider only concerns obtaining a browser binary. At runtime, Puppeteer can launch a browser process with puppeteer.launch() or connect to an already running browser with puppeteer.connect(). Browser contexts isolate cookies and local storage, which is useful when separate jobs must not share session state.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: true});
try {
const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.goto('https://example.com', {waitUntil: 'domcontentloaded'});
console.log(await page.title());
await context.close();
} finally {
await browser.close();
}
})();
Use browser.close() to close the browser process. Use browser.disconnect() when Puppeteer should disconnect from a browser it connected to while leaving that browser and its pages running. These lifecycle decisions are independent of which provider installed the binary. See the [browser management guide](https://pptr.dev/guides/browser-management).
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Browser executable not found | Download was skipped, install scripts did not run, or runtime uses a different cache | Run npx puppeteer browsers install, check the configured cache and permissions, or set a valid executable path. |
| Environment variable appears ignored | The app uses puppeteer-core, the variable is misspelled, or the process environment was not set where Puppeteer runs |
Use the full puppeteer package for configuration support, or explicitly configure the executable and browser lifecycle when using core. |
| Unexpected browser is selected | defaultBrowser in a configuration file and PUPPETEER_BROWSER disagree |
Check the environment first because it overrides applicable file settings; make the intended value explicit. |
| Custom provider download fails | Provider order, archive format, availability, or platform artifact is wrong | Check each provider independently, ensure the expected archive is served, and confirm fallback order and network access. |
| Browser installs but launch fails | Binary is incompatible with Puppeteer, lacks system dependencies, or cannot run in the target environment | Use the version paired with your Puppeteer release, install required OS dependencies, and test launch in the same container or host as production. |
| Works locally but fails in CI | Different platform, blocked postinstall downloads, cache permissions, or inconsistent versions | Install explicitly in the build, pin package and browser versions, and share a deliberate cache location between installation and runtime. |
8. Performance, reliability, and cost considerations
Browser management affects build time, reproducibility, and failure recovery. Downloading a browser during each ephemeral build adds network work; a deliberately managed cache can avoid repeated downloads, provided its contents and permissions are correct. A shared cache or artifact mirror can help standardize builds, but a custom provider also introduces another dependency that can fail or serve incompatible binaries.
For reliability, pin Puppeteer and use its compatible managed browser unless you have a concrete reason to own the binary source. Test the full install-and-launch path on each target platform. Browser automation also consumes CPU and memory while running; contexts isolate site storage, but they still belong to browser processes that need lifecycle cleanup. Cost depends on your build infrastructure and browser workload; Puppeteer’s documentation does not provide a universal price or benchmark, so measure download and runtime costs in your own environment.
9. Or skip the browser setup
If your goal is to capture a page rather than manage a browser binary, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call API returns a screenshot or PDF, so you do not need to install Puppeteer or maintain a browser for that capture:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before capture, along with supported newsletter popups and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing; response headers report the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 screenshots.
Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.
10. FAQ
Does “default provider” mean Chrome?
No. Chrome is the current default browser selection. The default provider is the installer’s final fallback download source.
Can I use a custom browser download source?
Yes, the install API accepts custom providers, but Puppeteer does not officially support them. You own compatibility checks and platform testing.
Should I use puppeteer or puppeteer-core?
Use puppeteer when you want Puppeteer’s managed browser and configuration behavior. Choose puppeteer-core when your application supplies browser setup itself; its configuration files and environment configuration are ignored.
How do I keep browser installs reproducible?
Pin the Puppeteer version, use its compatible browser build, install consistently on each target platform, and make cache and executable paths explicit in CI.


