ScreenshotNeo

BlogEngineering

Puppeteer Changelog: Browser Automation Updates

Puppeteer 25.12.0 is the latest listed release. See what changed, check browser compatibility, and upgrade safely from Puppeteer 25.

By the ScreenshotNeo team4 October 20269 min read

Latest listed release: Puppeteer 25.12.0, dated September 23, 2026. Its changes include Chrome and Firefox version rolls, an update to @puppeteer/browsers, temporary-profile cleanup, a drag-and-drop fix, and an accessibility shadow-host fix. For the browser versions paired with this release, the current support matrix lists Chrome for Testing 154.0.8037.57 and Firefox 156.0.1. Check the official pages again when you upgrade because releases and supported browser versions change.

This guide explains what the changelog means for an automation project, which Puppeteer and browser versions to use, the breaking changes in Puppeteer 25, and how to install, launch, and troubleshoot a basic browser task.

1. What changed in the latest Puppeteer release?

The official changelog combines changes for puppeteer and puppeteer-core. The 25.12.0 entry lists:

  • Browser rolls: Chrome for Testing 154.0.8037.57 and Firefox 156.0. These update the browser versions Puppeteer supports; they are not new Puppeteer API features.
  • Dependency update: @puppeteer/browsers moved from 3.2.2 to 3.2.3.
  • Launcher cleanup: temporary profiles are cleaned up when the process exits.
  • Drag-and-drop fix: the mouse button is released when a drag or drop fails.
  • Accessibility fix: an accessibility result for a text node in a shadow root returns its shadow host.
  • Additional browser roll: the notes also record a roll to Chrome 153.0.8010.47.

When scanning any Puppeteer release, separate changes to the JavaScript API from browser rolls and dependency or maintenance updates. A browser roll can matter to rendering and compatibility even when your application code does not change.

Source: Puppeteer changelog.

2. Which Puppeteer version and browser should you use?

Use the Puppeteer version that matches your project’s runtime and browser requirements, then consult the supported-browser matrix for the exact pair. Do not assume that an arbitrary Chrome or Firefox build is compatible just because Puppeteer can launch it.

Question Practical choice
Starting a new project? Install the current Puppeteer package and use its downloaded browser unless you have a reason to manage the browser yourself.
Need a specific browser build? Look up the Puppeteer version in the support matrix and pin compatible versions in your project and deployment.
Using a release missing from the matrix? The support page says to use the browser version supported by the immediately prior Puppeteer version, then verify behavior in your environment.
Automating Firefox? Stable Firefox support starts with Puppeteer 23.0.0. Check the matrix for the exact release you use.
Automating Chrome? Puppeteer uses CDP by default; WebDriver BiDi is also available. Choose and validate the protocol for your browser and setup.

The official support matrix currently pairs Puppeteer 25.12.0 with Chrome for Testing 154.0.8037.57 and Firefox 156.0.1. Treat those as release-specific compatibility data, not a promise that every browser build works with every Puppeteer version. See supported browsers before pinning.

3. Breaking changes to check before upgrading to Puppeteer 25

Puppeteer 25.0.0, released May 12, 2026, introduced changes that can break existing projects. Audit these before changing a production dependency:

  1. Node.js 22 or newer is required. Check the Node runtime in local development, CI, containers, and production. Upgrading the package without upgrading the runtime can prevent installation or execution.
  2. Puppeteer.product was removed. Search the codebase and dependencies for reads of this deprecated property and replace those assumptions with supported browser selection and configuration.
  3. executablePath and defaultArgs return Promises. Add await and update surrounding code that treated these methods as synchronous values.
import puppeteer from 'puppeteer';

const executablePath = await puppeteer.executablePath();
const defaultArgs = await puppeteer.defaultArgs();
console.log({ executablePath, defaultArgs });

Review the complete version 25.0.0 changelog entry and your project’s migration notes before upgrading. A useful upgrade sequence is to update the Node runtime first, adjust synchronous assumptions, upgrade in a branch, run representative browser flows, and then pin the version that passed your own checks.

4. Install and run a minimal Puppeteer script

The puppeteer package downloads a compatible browser during installation. The following JavaScript example launches it, opens a page, captures a screenshot, and closes the browser even if navigation or capture fails.

npm install puppeteer
// save as screenshot.mjs
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 900 });
  await page.goto('https://example.com', {
    waitUntil: 'networkidle2',
    timeout: 30_000,
  });
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}
node screenshot.mjs

networkidle2 waits for network activity to settle according to Puppeteer’s navigation wait condition, but it may not be appropriate for pages that keep connections open or load content continuously. In those cases, wait for a page-specific selector or use a bounded delay after navigation.

5. Launching, connecting, and isolating browser work

Launch a browser you manage

puppeteer.launch() starts a browser process. This is a straightforward option for scripts and workers that own the browser lifecycle. Always close the browser, including on errors, to release its process and temporary resources.

Connect to an existing browser

Use puppeteer.connect() when your deployment provides a browser process and connection endpoint. In that setup, your code attaches to the existing browser rather than launching one. The deployment must provide the appropriate endpoint and protocol; keep connection details private and follow the hosting environment’s instructions.

Isolate tasks with BrowserContexts

Use a separate BrowserContext for tasks that should not share browser state, such as cookies and storage. This keeps parallel jobs from accidentally reusing each other’s session state. Close each context when its task finishes. For browser lifecycle and context details, see Puppeteer browser management.

6. Headless Chrome: standard mode or chrome-headless-shell

Standard headless Chrome uses the regular Chrome browser in headless mode. Puppeteer also supports the separate chrome-headless-shell through headless: 'shell'. The shell does not fully match regular Chrome behavior, but the official guide describes it as potentially more performant for automation when its reduced feature set is sufficient.

const browser = await puppeteer.launch({ headless: true }); // regular Chrome headless
// or
const shellBrowser = await puppeteer.launch({ headless: 'shell' });

Choose based on the behavior your task needs. Prefer regular Chrome when feature fidelity matters; consider the shell when its behavior is sufficient and your own workload benefits. Do not assume a performance improvement without measuring your own pages and workload. Read Puppeteer headless modes for current distinctions.

7. Chrome DevTools Protocol and WebDriver BiDi

Puppeteer supports both Chrome and Firefox from v23.0.0 onward. Its FAQ says Chrome automation uses CDP by default and can also use WebDriver BiDi; BiDi is the default for Firefox automation. The FAQ also says Chrome automation through CDP will continue to be supported. BiDi support should not be read as a universal replacement for CDP.

When debugging protocol-specific behavior, record the Puppeteer version, browser and browser version, and protocol in use. Then compare that exact combination with Puppeteer’s support documentation. See the Puppeteer FAQ and supported browser matrix.

8. Browser downloads, configuration, and deployment

The full puppeteer package normally downloads a compatible browser during installation. puppeteer-core is intended for setups where you manage the browser yourself; provide the executable or connect to a managed browser as appropriate. Installation scripts may be disabled in some package-manager or deployment environments, which can leave Puppeteer without its expected downloaded browser.

  • Use Puppeteer’s configuration interface and documented environment variables to control browser installation and configuration.
  • Use PUPPETEER_CACHE_DIR to set the browser cache directory when your environment needs a non-default location.
  • Make sure the install step and runtime step use compatible configuration and can access the same browser cache or executable.
  • For Linux containers, check the documented system requirements and required browser packages for the chosen image.
  • If supplying your own Chrome or Firefox, verify it against the Puppeteer support matrix instead of assuming the latest system browser will work.

References: configuration interface, troubleshooting, system requirements, and browser management tools.

9. Common Puppeteer errors and fixes

Symptom Likely cause What to check
Could not find Chrome or browser executable The install script did not download a browser, the cache is missing, or runtime configuration points somewhere else. Confirm installation completed, inspect the configured cache directory, check PUPPETEER_CACHE_DIR, and ensure deployment retains the downloaded browser.
Browser executable exists but will not start Browser and Puppeteer versions may not match, or the environment lacks required system packages. Compare the exact versions with the support matrix and review the official system requirements for the OS or container.
Upgrade errors involving Node.js Puppeteer 25 requires Node.js 22 or newer. Check the runtime used by the terminal, CI job, container, and deployed service; update all of them consistently.
Code receives a Promise where it expected a string or array In version 25, executablePath and defaultArgs return Promises. Await the return value and propagate async behavior through the calling code.
Navigation times out on a page that appears loaded The selected network-idle condition may never occur on pages with persistent activity. Wait for a relevant selector, choose a suitable navigation condition, or use a bounded timeout strategy. Avoid unbounded waits.
Screenshot is blank, incomplete, or missing images The page may still be rendering, lazy content may not have loaded, or the selected viewport and capture timing do not match the page. Wait for a page-specific ready element, set the viewport before navigation, and validate whether the page needs scrolling or a longer bounded wait.
Behavior differs between local and CI The browser build, system dependencies, fonts, environment, or runtime configuration differs. Pin Puppeteer, use its paired browser where possible, align runtime and container configuration, and log versions with failures.
Firefox automation behaves differently from Chrome Browser support and protocol behavior differ. Check the exact Firefox version in the support matrix and consult the FAQ for protocol details.

10. Performance, reliability, and cost considerations

Performance

  • Reuse a browser process for related work instead of repeatedly starting one, while keeping tasks isolated with BrowserContexts where needed.
  • Set a viewport deliberately; large full-page captures consume more work than a viewport screenshot.
  • Wait for the condition your page actually needs. Overly broad network-idle waits can waste time or time out on active pages.
  • Evaluate chrome-headless-shell only when its feature set is sufficient, and compare it using your own representative tasks.

Reliability

  • Pin Puppeteer and browser versions when repeatable output matters, and update them deliberately.
  • Use timeouts and cleanup paths for browser, page, and context lifecycles.
  • Keep browser binaries and system dependencies consistent between installation and runtime environments.
  • Log the Puppeteer version, browser version, protocol, and failure stage so compatibility issues can be reproduced.

Cost

Puppeteer is a software library, so the relevant operational costs depend on where and how you run browsers: compute, memory, storage for browser binaries and artifacts, and engineering time maintaining the browser environment. The research sources do not establish a universal per-screenshot cost or benchmark; estimate cost against your own workload and hosting arrangement.

11. Or skip the browser setup

If your task is simply to capture a website, ScreenshotNeo is an alternative to running Puppeteer and maintaining a browser environment. One GET request returns an image or PDF. See the ScreenshotNeo API documentation for available parameters.

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

ScreenshotNeo accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; 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. Its MCP server provides screenshot tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a 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.

12. FAQ

What is the latest Puppeteer release?

The official changelog currently lists 25.12.0, dated September 23, 2026. Recheck the changelog before upgrading.

Does Puppeteer still support Chrome through CDP?

Yes. The Puppeteer FAQ says Chrome automation through CDP will continue to be supported, alongside WebDriver BiDi support.

When did Puppeteer add stable Firefox support?

Stable Firefox support began with Puppeteer v23.0.0. Use the supported-browser matrix to identify the compatible browser version for your release.

Should I use Puppeteer or ScreenshotNeo?

Use Puppeteer when you need programmable browser automation and control over the browser environment. Use ScreenshotNeo when you need a website screenshot or PDF through an API and want to avoid setting up the browser yourself.

Sources