Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Puppeteer lets a Node.js script control a browser: launch or connect to Chrome, open a page, navigate and interact with it, then close the browser or detach from it. For the current Puppeteer documentation snapshot, use Node.js 22.12 or later. Install puppeteer for a compatible browser downloaded as part of setup, or puppeteer-core if you manage the browser yourself.

Install Puppeteer and choose the right package

Before installing, check the current system requirements. Puppeteer’s documentation lists Node 22.12 or later for its current version; requirements can change between releases. Browser dependencies also vary by platform, and Linux may require system packages.

In a project directory, install the standard package:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install puppeteer

The puppeteer package installs the library and downloads a compatible Chrome for Testing browser. This is the simplest choice when your script should manage its own browser. The alternative, puppeteer-core, contains the library but does not download Chrome. Use it when you manage the browser installation or connect to a browser provided by another process or service.

npm install puppeteer-core

Package managers can block installation scripts, which may prevent the automatic browser download. If Puppeteer installs but cannot find a browser, follow the installation guide’s browser installation or install-script configuration instructions rather than reinstalling blindly.

Use ES modules or CommonJS consistently

The examples below use ES module imports. To run them in a Node.js project, set "type": "module" in package.json, or save the file with an .mjs extension. If your project uses CommonJS, load Puppeteer with const puppeteer = require('puppeteer'); and keep the asynchronous operations inside an async function.

Run a first browser script

This minimal script launches headless Chrome, opens a page, navigates to a URL, prints its title, and closes the browser:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  await browser.close();
}

Save it as index.js in a project configured for ES modules, then run node index.js. The await keywords matter: launching the browser, opening a page, navigating, and reading page data are asynchronous operations. The finally block closes a browser the script launched even if navigation or page work throws an error.

The usual workflow is to launch or connect to a browser, create a page, use the Page API to navigate and interact, and then close or disconnect according to who owns that browser’s lifecycle. Puppeteer’s getting-started guide gives a longer interaction example.

Navigate, wait for content, and interact with a page

A successful navigation does not guarantee that a site’s JavaScript-driven interface is ready for the next action. Prefer waiting for the specific element or text your task needs over adding an arbitrary delay. Puppeteer’s accessible locators provide a readable way to find and interact with interface elements.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });
  await page.goto('https://example.com');

  // Replace this with a locator and interaction for the page you automate.
  const heading = await page.locator('h1').waitHandle();
  console.log(await heading.evaluate(element => element.textContent));
} finally {
  await browser.close();
}

For a real site, select an element that the page actually renders and use a locator suited to it. Puppeteer’s documented search interaction demonstrates opening a search menu with the keyboard, filling an accessible locator, clicking the first result, and waiting for a text locator before reading the resulting title. See the getting-started example for that complete flow; its selectors and interaction sequence are specific to the example site, not universal selectors for other websites.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When content is asynchronous, wait for a meaningful condition before reading it. A fixed sleep can be too short on a slow response and waste time on a fast one. If the expected selector never appears, navigation, a changed page layout, authentication, or a failed request may be the cause; inspect the URL and page state rather than simply increasing the delay.

Save a page screenshot

Puppeteer can save a screenshot directly from the page it controls. This example writes a PNG file after visiting a URL:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'screenshot.png' });
} finally {
  await browser.close();
}

The path option tells Puppeteer where to save the image; the directory must be writable by the Node.js process. For screenshot options and page operations, consult the Page API documentation.

Choose how Puppeteer runs Chrome

Headless for non-visible automation

Puppeteer runs headless by default, so Chrome operates without opening a visible window. This suits scripts that navigate and inspect pages without needing a person to watch the browser.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Visible Chrome for debugging

Set headless: false when you need to watch the page and its interactions:

const browser = await puppeteer.launch({ headless: false });

A visible browser is useful for diagnosing a wrong URL, unexpected page state, or interaction that does not behave as expected. It is a launch option, not a change to how page operations are written.

Headless shell for a different runtime trade-off

The current headless guide documents headless: 'shell', which selects the separate chrome-headless-shell binary. It does not behave exactly like regular Chrome. The documentation identifies it as a possible choice when performance matters more than the complete feature set, not as a universal replacement for default headless Chrome. Check the headless modes guide before relying on browser-specific behavior.

Launch a browser or connect to one

Use puppeteer.launch() when the script starts the browser and is responsible for its lifecycle. Use puppeteer.connect() when an external process or service has already started a browser and provides a WebSocket endpoint. The connection details and browser setup must come from that environment; the Puppeteer documentation does not establish one universal deployment configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a launched browser, finish with await browser.close(). For a browser you connected to and do not own, call await browser.disconnect() to detach Puppeteer while leaving the browser and its pages running. These methods are not interchangeable: closing a connected browser can stop a process you did not intend to manage.

Use separate BrowserContexts when tasks need independent browser state. Puppeteer documents that cookies and local storage are not shared between contexts, which makes them useful for isolating sessions. See the Browser API for browser and context operations.

Handle failures and keep scripts reliable

Browser automation depends on the browser, target site, network, and runtime, so a script should allow failures to surface clearly and still release resources it owns. Keep page work inside a try/finally block as in the examples. For longer workflows, log the failing URL and the operation being attempted so that a timeout can be distinguished from a missing browser or a changed page.

Common problems and fixes

  • Executable or browser not found: The package may have installed without running its browser-download script. Follow the installation guide to install the supported browser manually with Puppeteer’s browser command or configure the package manager to allow the install script.
  • Browser fails to start on Linux: The system may be missing platform-specific libraries. Check the system requirements for the browser and platform you use; do not copy a dependency list meant for another distribution.
  • Navigation times out: The site may be slow, unreachable, or waiting on behavior that keeps the chosen navigation condition from completing. Verify the URL and connectivity, then choose a navigation or page-readiness condition appropriate to the task instead of adding a blind delay.
  • Element cannot be found: The selector or accessible name may not match the rendered page, or the element may appear only after client-side work. Inspect the current page and wait for the actual target before interacting.
  • Visible browser does not appear: The default is headless. Launch with { headless: false } when a visible window is required, and ensure the runtime can display one.
  • Browser unexpectedly stops: Confirm whether your code called browser.close() on a connected browser. Use browser.disconnect() when the external owner should keep it running.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, deployment, and cost considerations

Launching a browser creates work beyond a single HTTP request, so reuse a browser for related page tasks when appropriate, while separating independent user sessions with BrowserContexts. Close launched browsers when work completes; otherwise, browser processes can outlive the task that needed them. Whether a particular hosting service, container, or production environment needs additional configuration depends on that environment. The general Puppeteer documentation does not establish universal container flags or a one-size-fits-all deployment recipe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Installation downloads a compatible browser when using the standard puppeteer package, which affects setup time and storage. With puppeteer-core, you assume responsibility for supplying a compatible browser. No universal runtime cost or benchmark applies to Puppeteer; actual resource use depends on the browser, page, and execution environment.

Or skip the browser setup

If your task is simply to capture a website rather than automate its interface, ScreenshotNeo provides a screenshot API and MCP server. Its one-call request returns a screenshot or PDF, without requiring you to install and manage Puppeteer in your project. See the ScreenshotNeo API documentation for request options.

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

Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can Puppeteer automate a website without opening a Chrome window?

Yes. Headless mode is the default; set headless: false only when you need a visible browser.

Does puppeteer-core install Chrome?

No. It supplies the Puppeteer library, while you provide or connect to a browser yourself.

When should I use browser.disconnect() instead of browser.close()?

Disconnect when detaching from an externally managed browser that should remain running; close a browser your script launched and owns.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.