Open-source project
puppeteer/puppeteer avatar
puppeteer/puppeteer

Puppeteer v25: Browser Automation Through Two Protocols and a Package Split

JavaScript API for Chrome and Firefox

95,581 stars9,578 forksTypeScriptApache-2.0

At a glance

What is it?
Puppeteer is a TypeScript library that controls Chrome and Firefox via the DevTools Protocol or WebDriver BiDi. The v25 releases show a project still actively maintained, with a clear split between the full package and puppeteer-core.
Who is it for?
Adopt Puppeteer if you need a high-level JavaScript API for controlling Chrome or Firefox in headless mode, especially for testing or scraping. Do not adopt it if you prefer a browser-agnostic, standards-only approach, since the default package still downloads Chrome and the DevTools Protocol is Chrome-centric.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Puppeteer Solves and Who Needs It

Puppeteer solves the problem of scripting a real browser from JavaScript. It gives you a high-level API to drive Chrome or Firefox, without you having to write raw protocol messages. The intended users are developers who need automated browser interactions: end-to-end tests, page scraping, PDF generation, or capturing performance traces. The README's example shows a typical flow: launch a browser, open a page, navigate, set a viewport, and interact with the page using a locator. This is a library for people who would otherwise be stuck with lower-level tools or who need to reproduce real browser behaviour in a script.

Two Protocols, Two Browser Targets

The core design choice in Puppeteer is that it speaks two protocols: the Chrome DevTools Protocol and WebDriver BiDi. The DevTools Protocol is the older, Chrome-native protocol. WebDriver BiDi is a newer standard that aims to be cross-browser. The README states that Puppeteer controls Chrome or Firefox over either protocol. That is a significant architectural commitment. In practice, this means you can choose a protocol based on your browser target and your need for standard compliance. The documentation at pptr.dev/webdriver-bidi presumably explains the trade-offs, but the README itself does not say which protocol is used by default. The example code uses `puppeteer.launch()` with no protocol argument, so the default is likely DevTools Protocol for Chrome. This dual-protocol support is a strength, but it also means the API must abstract over two very different wire protocols, which can lead to inconsistent feature support.

The Package Split: puppeteer vs puppeteer-core

Installation is where the project makes an important distinction. The full package, `puppeteer`, downloads a compatible Chrome during installation. The alternative, `puppeteer-core`, does not download any browser. This split matters for two reasons. First, it affects disk footprint and install time. Second, it affects control: with `puppeteer-core`, you must point the library at a browser binary yourself, which is useful in environments where Chrome is already installed or where you need a specific version. The README's example shows that you can `import puppeteer from 'puppeteer'` or `import puppeteer from 'puppeteer-core'` and use the same API. That is a clean separation. However, the documentation does not explain how to specify a browser executable path for `puppeteer-core` in the README, so you would need to consult the API docs or troubleshooting guide.

Installation Pitfall: Blocked Install Scripts

A concrete failure mode is documented in the README. Modern package managers, including npm, pnpm, Yarn, Bun, and Deno, block dependency install scripts by default. Since Puppeteer's install script downloads the browser, a blocked script means the browser is never downloaded. The result is a runtime error when you try to launch. The README gives two workarounds. One is to run `npx puppeteer browsers install` after installation. The other is to configure your package manager to allow the install script, for example by adding `"puppeteer"` to `"allowScripts"` in `package.json` for npm. This is a real operational detail that will trip up many users. It also means that Puppeteer's default install is not fully reproducible unless you control the package manager settings or run the manual browser install step.

Getting Started: The Example Flow

The README's example is short but shows the core API surface. You import puppeteer, call `puppeteer.launch()` to start a browser, then `browser.newPage()` to create a page. `page.goto()` navigates to a URL. `page.setViewport()` sets the screen size. The example then uses `page.keyboard.press('/')` to open a search menu and `page.locator('::-p-aria(Search)').fill('automate beyond recorder')` to type into a search box. That locator syntax is notable: `::-p-aria` is a Puppeteer-specific pseudo-selector that targets elements by their accessible name. This is a higher-level abstraction than raw CSS selectors, and it reflects the project's move toward accessible, robust selectors. The example ends with a comment that says 'Wait and click', but the actual code is truncated. Still, the pattern is clear: launch, navigate, interact, and presumably close. The API is promise-based and async, which is standard for Node.js.

Beyond the Core: MCP and WebMCP

The README mentions two adjacent projects. One is `chrome-devtools-mcp`, a Puppeteer-based MCP server for browser automation and debugging. MCP stands for Model Context Protocol, a standard for connecting AI models to tools. This is a separate package, not part of Puppeteer itself, but it is built on Puppeteer. The other is WebMCP, an experimental API that Puppeteer supports. The README gives no details on WebMCP's mechanism or stability. This is a thin part of the documentation, and it signals that the project is expanding beyond its original testing-and-scraping niche into AI-driven automation. For an engineer evaluating Puppeteer, this is worth noting but not a reason to adopt it. The core value remains the browser control API.

Limitations and Wrong-Tool Cases

Puppeteer is not the right tool if you need to control browsers without a JavaScript runtime, or if you want a pure standards-based protocol with no Chrome bias. The default package downloads Chrome, which can be a problem in restricted network environments or when you need to run in a minimal container. The blocked install script issue is a real limitation that can cause confusing failures. Also, the README does not document how to handle multiple browser profiles, proxies, or authentication, so you would need to dig into the API docs. For simple tasks like fetching a single page's HTML, a lightweight HTTP client is more efficient. Puppeteer is a heavyweight dependency, especially with the browser download. If you only need to automate Firefox, you might look at alternatives that are Firefox-native, but the README suggests Puppeteer supports Firefox via WebDriver BiDi, so that is not a disqualifier.

Alternatives and How They Differ

The main alternative to Puppeteer is Playwright, a similar browser automation library. Playwright also controls Chrome and Firefox, but it uses its own protocol abstraction and has a different installation model. Playwright downloads browser binaries to a central cache and requires you to run a separate install command (`npx playwright install`). Puppeteer's default is to download during npm install, which is more convenient but can be blocked. Playwright also supports multiple browser vendors out of the box, while Puppeteer's Firefox support is via WebDriver BiDi, which is still maturing. Another alternative is Selenium WebDriver, which uses the WebDriver protocol natively and is language-agnostic. Selenium is more verbose and lower-level, but it is a W3C standard and has broader language support. The key difference in approach is that Puppeteer is JavaScript-first and tightly coupled to Chrome's DevTools Protocol, while Playwright and Selenium aim for cross-browser parity with their own abstractions. For a JavaScript-only project, Puppeteer is a natural fit, but if you need cross-language or cross-browser parity, the alternatives have an edge.

Maintenance and Upgrade Cost

The repository shows active maintenance, with releases v25.8.0 and v25.9.0 in August 2026, less than two weeks apart. The project is not archived. The license is Apache-2.0, which is permissive for commercial use, but you should check the license text for any patent clauses. The maintenance cost for you, the user, comes from keeping up with new releases. The package split means you have two packages to track: `puppeteer` and `puppeteer-core`. Upgrading is straightforward if you use semver, but the project may introduce breaking changes in major versions. The README does not mention a migration guide, but the pptr.dev site likely has one. The install script issue means that every time you update the package, you need to ensure the browser download still works or run the manual install command. That is a recurring operational cost. The dual-protocol support also means that features may behave differently depending on which protocol you use, so testing after upgrades is important.

Editorial conclusion

Adopt Puppeteer if you need a high-level JavaScript API for controlling Chrome or Firefox in headless mode, especially for testing or scraping. Do not adopt it if you prefer a browser-agnostic, standards-only approach, since the default package still downloads Chrome and the DevTools Protocol is Chrome-centric. Before adopting, verify your package manager's install script policy, because a blocked script means no browser download and runtime errors. Check the WebDriver BiDi support level for your target browser, as it is not the default in all examples. If you want no browser download and full control over browser binaries, use puppeteer-core instead.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes