ScreenshotNeo

BlogComparisons

Puppeteer vs. Puppeteer Core: What’s the Difference?

Puppeteer downloads a compatible browser by default; Puppeteer Core leaves browser setup to you. Compare install behavior, launch options, use cases, and fixes.

By the ScreenshotNeo team4 October 20267 min read

puppeteer is the higher-level package: a normal installation downloads a supported browser for you. puppeteer-core provides the automation library without downloading Chrome, so your application must supply a local browser or connect to a remote one. The automation APIs are shared; the difference is who manages the browser setup.

Choose puppeteer for a straightforward local setup using Puppeteer’s downloaded browser. Choose puppeteer-core when your environment already provisions a browser, you need to choose its executable or channel, or you connect to a remote browser. The official [installation guide](https://pptr.dev/guides/installation) describes these roles and the browser download behavior.

At a glance

Question puppeteer puppeteer-core
Does installation download a browser? Normally downloads a supported Chrome for Testing build and headless shell. No automatic Chrome download.
Who manages the browser? Puppeteer provides a convenient default; you can customize it. Your application or infrastructure provides it.
What is needed to launch? Usually no browser path for the default downloaded browser. Provide executablePath or channel.
When is it a good fit? Local automation and simpler initial setup. Preinstalled, explicitly managed, or remote browsers.
Do they use different page automation APIs? They share Puppeteer’s automation API workflow.

Install and run Puppeteer

Install the full package when you want Puppeteer to manage its supported browser download. The browser download occurs during installation, so build and deployment environments need to allow that install step or provide another documented installation path.

npm install puppeteer

Save this as capture.js and run it with Node.js:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  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();
  }
})();

The same basic launch, page creation, navigation, and screenshot workflow is available with Core. See the official [getting started guide](https://pptr.dev/guides/getting-started).

Install and run Puppeteer Core

Install Core when your runtime owns browser provisioning or connects to a browser managed elsewhere.

npm install puppeteer-core

For a local browser, set executablePath to the browser binary installed in your environment. The path varies by operating system, package, container image, and deployment platform; do not assume a path from another machine will work.

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/chrome',
    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();
  }
})();

You can use channel to select an installed browser channel instead of specifying a binary path. A Core launch must be given a usable browser selection; the [launch API reference](https://pptr.dev/api/puppeteer.puppeteernode.launch) documents launch options and compatibility caveats.

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

Channel names and installed browser availability depend on the environment. If neither the requested channel nor the executable exists, launch fails. For a remote browser, use Puppeteer’s connection workflow with the valid endpoint and credentials supplied by that browser service; endpoint formats and authentication are service-specific, so use that provider’s documentation rather than inventing a URL.

Which package should you use?

  1. Use puppeteer if you want a local browser downloaded and paired with Puppeteer by default, and your installation environment permits the browser install step.
  2. Use puppeteer-core if your application or platform provisions Chrome, you need a specific browser binary/channel, or you connect to a remote browser.
  3. Check version compatibility when managing the browser yourself. Puppeteer releases are paired with browser versions to reduce protocol incompatibilities. Consult the [supported browsers table](https://pptr.dev/chromium-support/) for the version you install.

The supported-browser documentation is version-specific. At the research snapshot, the page listed Puppeteer v25.12.0 with Chrome for Testing 154.0.8037.57 and Firefox 156.0.1. Treat those as release entries, not permanent requirements; check the table for your installed release. The Puppeteer FAQ explains the compatibility rationale and protocol support: [Puppeteer FAQ](https://pptr.dev/faq).

Browser management and configuration

Downloaded browser versus provisioned browser

With puppeteer, the default download reduces the amount of browser setup in a local project. You still need to make sure the browser can run in the target environment, including its operating-system libraries, permissions, and available resources.

With Core, browser lifecycle is your responsibility: install or provision the binary, choose when it is updated, ensure the executable is reachable, and pair it with a compatible Puppeteer version. This can fit controlled containers and remote browser setups, but it adds deployment configuration.

Install scripts and configuration

Some package managers or build policies block dependency install scripts. If Puppeteer’s postinstall step is skipped, the package may be present while its managed browser is missing. The installation guide documents allowing Puppeteer’s install script or installing a browser manually with npx puppeteer browsers install.

Configuration behavior can differ by package and release. The dossier’s configuration reference is for the Next documentation channel and says Puppeteer configuration files and environment variables are ignored by Core. Verify this against the stable docs for the exact package version before relying on configuration files or environment settings. Core’s launch needs should be explicit in application code.

Runtime requirements

Requirements change with releases. The research snapshot’s system requirements page listed Node 22.12+ and TypeScript 5.0.1+ when using TypeScript. Check the [system requirements](https://pptr.dev/guides/system-requirements) for the release you plan to deploy.

Common errors and fixes

Symptom Likely cause Fix
“Could not find Chrome” or a missing browser at launch The install script was blocked, the managed browser was not downloaded, or Core was installed without provisioning a browser. For Puppeteer, allow its documented install step or run npx puppeteer browsers install. For Core, install a compatible browser and provide its actual path or channel.
Core launch fails immediately No executablePath or channel was provided, or the selected browser is absent. Set a valid browser path/channel and confirm the process can execute it.
Browser executable exists but will not start Runtime libraries, permissions, sandbox policy, or container configuration are incompatible with the deployment. Check the browser’s stderr and deployment image requirements; install required OS dependencies and use the platform’s documented browser settings.
Automation behaves differently after upgrading Puppeteer and the managed or external browser versions may have changed or may not be a supported pairing. Check the supported-browser table for the installed Puppeteer release and pin a compatible browser/package combination when reproducibility matters.
Works locally, fails in CI CI may block install scripts, lack browser dependencies, or use a different executable path/user. Provision the browser in the CI image, permit or run the documented install step, and verify paths and permissions as the CI user.

Performance, reliability, and cost

Package choice alone does not guarantee faster captures. Browser startup, page load, the page’s network activity, and whether a browser process can be reused are practical factors. A managed download reduces setup decisions but adds browser installation and storage to the build. Core avoids that download and can use an existing or remote browser, while shifting provisioning, updates, and compatibility checks to your system.

For reliable automation, close browsers in a finally block, set navigation and operation timeouts appropriate to the page, and avoid treating network-idle as proof that every application is ready: pages with persistent connections may never become idle. When using a remote browser, account for network and service availability as part of the capture path.

The packages themselves are open source; the practical cost difference is operational: browser storage/download time and maintenance versus browser infrastructure you already operate or separately provide. The research does not establish a cost benchmark between those setups.

Or skip the browser setup

If your goal is to get a website screenshot rather than build a browser automation workflow, [ScreenshotNeo](https://screenshotneo.com) is a website screenshot API and MCP server from Yorker Media. One GET request returns a PNG, JPEG, WebP, or PDF. The [API documentation](https://screenshotneo.com/docs/) has the request options.

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo removes cookie/consent banners, newsletter popups, and chat widgets before the shot; those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its 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. Every feature is on every plan.

Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card.

FAQ

Can I switch from puppeteer to puppeteer-core?

Usually the page automation code can remain similar because the API workflow is shared. Update installation and browser provisioning, then make the browser selection explicit when launching Core.

Does Core include Chromium?

No. Core does not automatically download Chrome during installation. Your environment must provide a browser or a remote connection.

Does puppeteer only support Chrome?

Browser support and protocol behavior depend on the Puppeteer release. The project documentation describes Chrome and Firefox support; check the supported-browser page and relevant protocol guide for your version.

Does Puppeteer Core read Puppeteer config files?

Check the stable configuration documentation for your installed version. The cited configuration distinction in the research dossier is from the Next documentation channel.