ScreenshotNeo

BlogComparisons

Puppeteer vs. Selenium: Which Is Better for Browser Automation?

Puppeteer suits JavaScript teams automating Chrome or Firefox; Selenium fits broader language, browser, and Grid needs. Compare protocols, setup, and code before choosing.

By the ScreenshotNeo team4 October 20269 min read

Neither Puppeteer nor Selenium is universally better. Choose Puppeteer when your team works in JavaScript and its documented Chrome or Firefox support and protocol features cover the job. Choose Selenium when you need language bindings beyond JavaScript, a broader documented browser matrix, or Selenium Grid orchestration. Before committing, verify the exact browser, protocol, and feature combination you plan to deploy; do not assume one framework is always faster.

This guide compares their scope and tradeoffs, then gives runnable JavaScript examples for each. If your task is only to capture a page as an image or PDF, ScreenshotNeo is an alternative to try first: it provides a screenshot API, bills only clean shots, and has a free plan. It does not replace either framework for general browser interaction or test automation.

1. The short decision guide

Need Starting point Why
JavaScript automation of Chrome or Firefox Puppeteer It is a JavaScript library, and its current documentation covers both browsers.
Multiple programming languages Selenium Puppeteer’s FAQ notes that Selenium provides bindings for more languages.
Safari or Edge in the required browser matrix Selenium Selenium documents browser-specific functionality for Safari and Edge, among other browsers.
Distributed execution using Selenium Grid Selenium Grid is one of the large-scale orchestration tools identified in Puppeteer’s FAQ.
A Puppeteer workflow requiring CDP-specific capabilities Puppeteer with CDP Chrome uses CDP by default; check the BiDi support list before switching protocols.
A screenshot or PDF without maintaining browser automation ScreenshotNeo One API request can return a screenshot or PDF; it is focused on capture, not full browser testing.

These are starting points, not guarantees that every operation works identically across versions. Check the official Puppeteer FAQ, Puppeteer supported browser versions, and Selenium’s WebDriver documentation and browser-specific documentation.

2. What each framework is designed to cover

Puppeteer: direct JavaScript browser control

Puppeteer is a JavaScript library maintained by the Chrome Browser Automation team. Its current documentation covers Chrome and Firefox. Puppeteer uses Chrome DevTools Protocol (CDP) for Chrome by default and WebDriver BiDi by default for Firefox. Chrome can also be automated through BiDi, but some Puppeteer features are not supported over BiDi.

Puppeteer releases are associated with browser versions. Its supported browser page maps releases to Chrome for Testing and Firefox versions, and advises using the browser version mapped to the immediately prior listed Puppeteer version when an exact version is not listed. Consult that mapping when reproducibility matters.

Selenium: language bindings, browser-specific support, and orchestration

Selenium WebDriver drives browsers locally or through a Selenium server. Selenium documents browser-specific functionality for Chrome, Edge, Firefox, Internet Explorer, and Safari. Each browser can have custom capabilities and features, so check the documentation for the specific browser you need. Selenium also offers language bindings beyond JavaScript and Selenium Grid for orchestration across machines.

Protocols need their own check

WebDriver BiDi is supported by both projects, but that does not mean their implementations or available features are interchangeable. Puppeteer’s BiDi guide lists unsupported operations, including some emulation capabilities, CDP-specific interfaces, accessibility, coverage, tracing, and other methods. An unsupported operation can raise an UnsupportedOperation error. For Puppeteer on Chrome, CDP remains the default, and the project says it will continue supporting CDP.

Selenium’s WebDriver documentation describes WebDriver BiDi as a bidirectional protocol that adds a WebSocket connection so scripts can react to browser events. Check the framework’s current documentation for the exact browser and feature support you need.

3. Runnable JavaScript examples

The examples below open a page, wait for a heading, print its text, save a screenshot, and close the browser even if an operation fails. They use the same target URL so you can compare the setup. Install the required browser or driver dependencies for your environment and follow each project’s current installation instructions.

Puppeteer

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
  await page.locator('h1').wait();
  console.log(await page.locator('h1').map(el => el.textContent).wait());
  await page.screenshot({ path: 'example.png', fullPage: true });
} finally {
  await browser.close();
}

Save it as capture.mjs and run it in a Node.js project with Puppeteer installed. Puppeteer’s own browser and version mapping is documented at pptr.dev/chromium-support. If you use an externally installed browser or choose a different protocol, follow the current launch options in Puppeteer’s documentation and validate feature support.

Selenium WebDriver for JavaScript

import { Builder, By, until } from 'selenium-webdriver';
import chrome from 'selenium-webdriver/chrome.js';

const options = new chrome.Options();
options.addArguments('--headless=new');

const driver = await new Builder()
  .forBrowser('chrome')
  .setChromeOptions(options)
  .build();

try {
  await driver.get('https://example.com');
  const heading = await driver.wait(
    until.elementLocated(By.css('h1')),
    10000,
    'Timed out waiting for the page heading'
  );
  console.log(await heading.getText());
  const png = await driver.takeScreenshot();
  const fs = await import('node:fs/promises');
  await fs.writeFile('example.png', png, 'base64');
} finally {
  await driver.quit();
}

Save it as capture.mjs in a project with selenium-webdriver installed. Selenium’s driver setup and browser options vary by browser and deployment environment; start with its driver sessions guide and browser options guide. For remote execution, Selenium documents Remote WebDriver as part of driver sessions.

4. Compare the tradeoffs that affect your project

Axis Puppeteer Selenium What to decide
Language JavaScript library Bindings in more languages Use the language your team can maintain and support in its environment.
Documented browser scope Chrome and Firefox Chrome, Edge, Firefox, Internet Explorer, Safari documentation List the exact browser products and versions required by your tests.
Protocol CDP by default for Chrome; BiDi is also available; Firefox uses BiDi by default WebDriver, with WebDriver BiDi documented Check whether the API feature you need is available over the chosen protocol.
Browser version planning Release-to-browser mapping is published Browser-specific driver and capability setup Pin and review the compatible browser and driver setup in your deployment.
Orchestration Direct browser automation library Selenium Grid is an orchestration option Decide whether you need distributed sessions and how your team will operate them.
Performance No universal winner established by the documentation reviewed No universal winner established by the documentation reviewed Measure your actual scenario, environment, browser, and protocol.

5. Make a choice in five steps

  1. Write down the target browsers. Include browser family and the versions your users or CI environment require.
  2. Choose the language and runtime. If the automation must live in a non-JavaScript codebase, Selenium’s wider language bindings are a relevant advantage.
  3. List required browser features. Include events, emulation, screenshots, input actions, accessibility data, network controls, or other APIs the workflow depends on.
  4. Check protocol support at the versions you will deploy. For Puppeteer, explicitly check whether you will use CDP or BiDi and whether the required feature is supported over that protocol.
  5. Plan execution and maintenance. Consider local versus remote runs, Selenium Grid if needed, browser and driver updates, and how failures will be diagnosed.

If both frameworks meet the requirements, build a small representative workflow in each and compare maintenance effort and behavior in your own environment. The official sources covered here describe capabilities, not a controlled head-to-head performance result, so they do not support a blanket speed or reliability ranking.

6. Reliability, performance, and cost considerations

Reliability

  • For Puppeteer, keep the library and browser versions aligned with its published support mapping. This helps avoid unexpected changes in the underlying protocol implementation.
  • For Selenium, verify the selected browser’s driver and options for your environment. Browser-specific features are not necessarily identical across vendors.
  • For either framework, wait for the actual element or condition your task needs instead of relying on a fixed pause. Keep timeouts bounded and report which condition timed out.
  • Run the same critical workflow in the browser and protocol combinations you intend to ship. Do not infer support from a different browser or protocol.

Performance

There is no universal speed winner established by the cited official documentation. Measure the whole workflow: browser startup, navigation, waiting, application work, capture or assertions, and teardown. Use the same target, browser version, machine type, concurrency, and readiness condition for a useful comparison. Repeated runs can also reveal whether a difference comes from startup overhead or from the page task itself.

Cost and operational load

Framework choice alone does not determine operating cost. Account for the machines and browser processes needed for your workload, CI minutes, remote execution infrastructure, and the work of maintaining browser and driver versions. Selenium Grid can be relevant when you need distributed orchestration; Puppeteer’s version mapping can matter when keeping a browser paired with the library. Estimate with your own execution volume and infrastructure costs rather than assuming one framework is cheaper.

7. Troubleshooting common problems

Symptom Likely cause What to check
Puppeteer launch fails after a browser update The browser version may not match the Puppeteer release’s supported mapping, or the runtime may not have the expected browser available. Check Puppeteer’s supported browser table and launch configuration; align the browser version with the documented mapping.
A Puppeteer call throws UnsupportedOperation with BiDi The operation is not supported over WebDriver BiDi. Check the BiDi feature list. If the workflow needs a CDP-only capability on Chrome, verify whether CDP is the appropriate protocol.
Selenium cannot start a browser session Browser, driver, options, or environment configuration may not match. Check Selenium’s driver sessions, browser options, and browser-specific documentation for the chosen browser and deployment.
An element lookup times out The page may not have reached the state your script expects, the selector may be wrong, or navigation may have failed. Confirm the final URL and selector, wait for a meaningful page condition, and capture browser or driver logs for diagnosis.
Local run works but remote run fails The remote machine may have different browser versions, capabilities, network access, or headless behavior. Compare the remote browser setup and options with the local setup; reproduce using the remote configuration.
Different browsers produce different results Browser-specific behavior or capabilities can differ. Consult the browser-specific documentation and test the behavior in each required browser rather than assuming parity.

8. Or skip the browser setup

If the job is to capture a URL as an image, ScreenshotNeo offers a single-request screenshot API. Its API returns PNG, JPEG, WebP, or PDF output. The examples below save the response for a Stripe page as WebP. See the ScreenshotNeo API documentation for request options.

cURL

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

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
    f.write(r.content)

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

ScreenshotNeo accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response indicates the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan. ScreenshotNeo is a screenshot service, so use Puppeteer or Selenium when you need to interact with a browser or run general browser tests.

Sign up for 1,000 free screenshots a month, with no card required.

9. Frequently asked questions

Is Puppeteer better than Selenium for testing?

It depends on your test language, browsers, protocol features, and execution setup. Puppeteer is a reasonable fit for JavaScript tests targeting Chrome or Firefox when its APIs cover the workflow. Selenium is a reasonable fit when you need broader language bindings, a wider documented browser matrix, or Grid.

Does Puppeteer support Firefox?

Yes. Current Puppeteer documentation covers Firefox; Firefox automation uses WebDriver BiDi by default. Check the supported browser mapping for the Puppeteer release you plan to use.

Can Puppeteer use WebDriver BiDi with Chrome?

Yes. Chrome uses CDP by default, and Puppeteer can use BiDi when configured to do so. Some features are unsupported over BiDi, so consult its support guide before changing protocols.

Can ScreenshotNeo replace Puppeteer or Selenium?

For URL-to-image or URL-to-PDF capture, it can avoid running and maintaining your own browser process. It does not provide general browser interaction or replace a framework used to test application behavior.

Sources