ScreenshotNeo

BlogHow-to

How Puppeteer Gets Browser Download URLs

Use Puppeteer’s public getDownloadUrl API to build a browser archive URL, choose a download host, or install the browser directly.

By the ScreenshotNeo team4 October 20268 min read

Direct answer: Puppeteer’s public getDownloadUrl(browser, platform, buildId, baseUrl?) helper returns a URL for the browser archive matching the browser, platform, and build ID you provide. Import it from @puppeteer/browsers. It constructs the archive URL; it does not download, unpack, install, or launch the browser.

Use getDownloadUrl when you need the address itself. Use install when you want Puppeteer’s browser management package to fetch and install the archive. Use puppeteer’s standard package installation when its automatic Chrome for Testing download fits your setup. This guide follows the public API documented as version 25.10.0 and adjacent documentation displayed as 25.12.0, accessed October 3, 2026. Check your installed package’s types and docs if you use an older release.

Get a browser download URL

Install the browser management package if it is not already a dependency:

npm install @puppeteer/browsers

Then provide a valid browser, platform, and exact build ID. This runnable Node.js example uses the Chrome for Testing build ID shown in the official API example; replace it with the build you actually need.

import {Browser, BrowserPlatform, getDownloadUrl} from '@puppeteer/browsers';

const url = getDownloadUrl(
  Browser.CHROME,
  BrowserPlatform.LINUX,
  '116.0.5793.0',
);
console.log(url.href);

The function signature is getDownloadUrl(browser, platform, buildId, baseUrl?) and its return type is URL. The first three arguments identify the artifact. The optional fourth argument changes the base host. Use the enum values exported by your installed package, rather than guessing a platform string. The exact build ID must exist for the selected browser and platform. See the official API reference and browser management API.

Common platform and build mistakes

  • Wrong platform: an archive for Linux will not be the macOS or Windows build. Select the runtime platform you intend to install or download for.
  • Wrong build ID: a version string from another browser release channel or browser may not identify an archive. Use a build ID valid for the chosen browser.
  • Assuming the URL is a download: the helper returns the address only. Fetching the archive and extracting it are separate operations.
  • Assuming every Puppeteer version is identical: check the installed @puppeteer/browsers package API when maintaining older projects.

Choose a download host

Pass baseUrl as the fourth argument when you need a different host that serves the expected archive layout. The install API also accepts baseUrl. Puppeteer documents these default install hosts: Chrome for Testing uses https://storage.googleapis.com/chrome-for-testing-public, and Firefox Nightly uses https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central. These are documented defaults, not universal URLs for every browser artifact or provider.

import {Browser, BrowserPlatform, getDownloadUrl} from '@puppeteer/browsers';

const url = getDownloadUrl(
  Browser.CHROME,
  BrowserPlatform.LINUX,
  '116.0.5793.0',
  'https://downloads.example.invalid/chrome-for-testing',
);
console.log(url.href);

The example host is deliberately a placeholder; replace it with a host you operate and whose path structure contains the requested artifact. Forming a URL does not check that the file exists or is compatible. For configuration and install behavior, consult the install options reference and configuration reference.

When configuration is preferable

If Puppeteer itself performs the install, use its documented configuration or install options instead of separately constructing a URL. The configuration reference documents browser-specific download base settings, including Firefox’s downloadBaseUrl and its environment-variable override. The exact setting depends on the browser and Puppeteer version; check the current configuration reference before adding it to a project.

Get the URL, install the browser, or launch it

Goal Use What it does
Know the archive address getDownloadUrl Returns a URL for one browser, platform, and build ID.
Download and unpack an archive install from @puppeteer/browsers Installs the specified browser build in a cache directory, optionally using a base URL.
Use Puppeteer’s default browser setup puppeteer package install Automatically downloads a recent Chrome for Testing binary and chrome-headless-shell according to the installation guide.
Connect to a browser you manage puppeteer-core Does not download Chrome during package installation; supply a browser endpoint or executable when launching.

For the install API, provide a browser and build ID, and optionally a cache directory and base URL. The URL helper does not need a cache directory because it does not install anything.

import {Browser, install} from '@puppeteer/browsers';

const installed = await install({
  browser: Browser.CHROME,
  buildId: '116.0.5793.0',
  cacheDir: './.browser-cache',
});
console.log(installed.executablePath);

This is an install example, not URL-only retrieval. Review the installed package’s TypeScript definitions for required options in your version. The official installation guide explains package behavior and manual browser installation.

Why Puppeteer may not download Chrome

The package choice and install-script behavior are the first things to check.

  1. Confirm the dependency is puppeteer, not puppeteer-core. The latter deliberately leaves browser management to you.
  2. Check whether your package manager blocked lifecycle scripts. If so, run npx puppeteer browsers install (or the equivalent command for your package manager) after installation.
  3. Check the install output and network access to the configured host. A proxy may need to be configured for the downloading process; Puppeteer’s guide notes that proxy-agent is needed to use a proxy for downloading.
  4. Check disk space and the configured cache path. Since Puppeteer v19.0.0, the default cache directory is $HOME/.cache/puppeteer; configuration or PUPPETEER_CACHE_DIR can change it.
  5. If you manage the browser yourself with puppeteer-core, install a compatible browser and pass its executable path or connect to a remote browser when launching.

For launch configuration and executable paths, see the configuration guide and launch options reference.

Using a custom provider or mirror

A custom BrowserProvider can construct URLs for another source or archive layout. Implement getDownloadUrl(options) and getExecutablePath(options), then integrate the provider with your browser management flow. This is for cases where the supported base URL option is insufficient.

Puppeteer’s documentation says, “Custom providers are NOT officially supported.” It also says Puppeteer tests and guarantees Chrome for Testing binaries. A custom provider’s URL is not validated in advance, so an unavailable archive may fail later during download. You own compatibility checks, testing, and maintenance; a URL that can be formed is not evidence that the archive will work. See the BrowserProvider reference.

Troubleshooting

Symptom Likely cause Fix
getDownloadUrl is missing or the import fails The package is absent, the import path is wrong, or the installed version differs from the documented API. Install or update @puppeteer/browsers as appropriate and inspect that version’s exported types and API docs.
The URL looks plausible but returns not found The browser, platform, build ID, or base URL does not correspond to an available archive. Use a verified build ID for that browser and platform; confirm the host serves the expected layout.
Browser installation completes but launch cannot find it The launch configuration points at a different cache or executable path. Use the path returned by the install operation, or align Puppeteer’s configured cache directory and launch path.
No browser appears after package installation puppeteer-core was installed or lifecycle scripts were disabled. Use puppeteer for its automatic supported download, or run the documented browser install command.
Download fails behind a proxy The download process is not configured to use the environment’s proxy. Follow Puppeteer’s proxy guidance, including its documented proxy-agent requirement.
Custom mirror downloads an incompatible browser The mirror served an unexpected build or archive layout. Validate archive identity and compatibility, and maintain the provider yourself; custom providers are not officially supported.

Performance, reliability, and cost

getDownloadUrl itself only constructs a URL; browser archive transfer and extraction are the costly parts. Puppeteer’s installation guide publishes approximate download sizes of about 170 MB for macOS, 282 MB for Linux, and 280 MB for Windows. These are the guide’s estimates, not measurements for this article. Account for additional disk use after extraction, cache duplication across build IDs, and the time needed to fetch artifacts in CI.

Keep a shared browser cache where practical, configure its directory deliberately, and avoid reinstalling the same build in every job. For repeatable builds, pin the browser build ID alongside the Puppeteer dependency and ensure the artifact remains available to your environment. Network failures, proxy behavior, host retention, disk limits, and custom mirror changes can all affect reliability. Puppeteer’s supported Chrome for Testing binaries have its documented compatibility guarantee; custom providers put validation and upkeep on you.

Or skip the browser setup

If your goal is to capture a website image or PDF rather than manage a local browser archive, ScreenshotNeo provides a screenshot API and MCP server. Its capture flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing state in headers. AI agents can use the MCP tools take_screenshot, get_page_info, and capture_pdf.

One GET request returns an image or PDF. This cURL example saves a WebP screenshot of Stripe:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Equivalent Python:

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)

Equivalent Node.js:

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 options and setup. It includes full-page and selector captures, device presets and custom viewports, custom CSS and JavaScript, wait conditions, headers and cookies, caching, async jobs, bulk capture, and more. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000. Sign up for free and make your first capture.

FAQ

Does getDownloadUrl download Chrome?

No. It returns a URL object. Use install to download and unpack a browser through @puppeteer/browsers.

Can I use the returned URL with cURL?

Yes, once you have verified the URL points to the intended archive. The helper does not validate that the URL is reachable or that the downloaded file is compatible.

Does puppeteer-core install a browser?

No. Its package installation does not download Chrome. Manage a local browser yourself or connect to a remote browser.

Can I use a mirror?

Use the documented base URL option when its expected layout fits. A custom provider supports more extensive changes, but it is not officially supported and requires your own compatibility checks.