ScreenshotNeo

BlogGuides

Puppeteer Getting Started: Run Your First Browser Script

Install Puppeteer, launch a browser, open a page, and run your first script. Includes visible mode, browser setup fixes, and a screenshot API option.

By the ScreenshotNeo team4 October 20269 min read

Puppeteer getting started is a short sequence: install the puppeteer package, launch its compatible browser, create a page, navigate to a URL, read or interact with the page, then close the browser. The first script below prints a page title and closes the browser even if navigation fails.

1. Install Puppeteer

For the simplest local setup, use puppeteer. It downloads a compatible Chrome for Testing browser during installation. Puppeteer’s official installation guide also lists Yarn, pnpm, and Bun commands; use the package manager your project already uses. [Puppeteer installation guide]

npm install puppeteer

The browser download is substantial: Puppeteer’s current documentation estimates approximately 170 MB on macOS, 282 MB on Linux, and 280 MB on Windows. These are approximate figures, not fixed requirements. Allow for the download and disk space in CI or a fresh development environment. [Installation and download size]

Use a JavaScript file with an .mjs extension for the example below. If your project uses CommonJS, see the module note in the next section. Check the current Puppeteer package’s Node.js engine requirement before choosing a Node version; do not assume it from an older tutorial.

2. Run your first browser script

import puppeteer from 'puppeteer';

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

Save this as first-browser.mjs, then run:

node first-browser.mjs

The script prints the page’s title. Its steps are:

  1. puppeteer.launch() starts the browser process. By default, it runs headless, without a visible window.
  2. browser.newPage() creates a new tab.
  3. page.goto(url) navigates that tab to the URL and waits for navigation according to its configured lifecycle condition.
  4. page.title() reads the document title.
  5. The finally block closes the browser process, including when a navigation or page operation throws an error.

This follows Puppeteer’s documented launch, page creation, navigation, read, and close workflow. [Official getting started guide]

ES modules and CommonJS

The example uses top-level await in an ES module. The .mjs extension makes that explicit. If your project sets "type": "module" in package.json, you can use an .js file instead. For a CommonJS project, wrap the work in an async function and use require:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://developer.chrome.com/');
    console.log(await page.title());
  } finally {
    await browser.close();
  }
})();

3. Add an interaction and read a result

Once navigation works, set a viewport, find an element with a locator, interact with it, and read a result. This example uses the current locator API style shown in Puppeteer’s guide. Replace the selectors and expected text with values from the page you are automating.

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://developer.chrome.com/');

  const heading = page.locator('h1');
  await heading.wait();
  console.log(await heading.map(node => node.textContent).wait());
} finally {
  await browser.close();
}

Locators let you target elements and wait for them as part of an interaction. Puppeteer’s getting-started guide also demonstrates matching by accessible name or text, setting a viewport, waiting for a result, and reading page content. Prefer a locator that describes the intended element clearly; a selector that matches several elements may need to be narrowed. [Getting started: page interaction]

4. Choose the right browser setup

Choice Use it when Trade-off
puppeteer You want the easiest local first run. Installation downloads the browser build Puppeteer pairs with its release.
puppeteer-core Your application manages the browser or connects to a remote browser. It does not download a browser; you must provide the browser setup explicitly.
Bundled Chrome for Testing You want the documented compatibility baseline. Uses the browser version paired with Puppeteer.
System Chrome or another browser install Your environment requires a centrally managed browser. You take on version compatibility; Puppeteer says it works best with bundled Chrome for Testing and does not guarantee other Chrome versions.
Headless run You want background automation or a CI job. No browser window is shown.
Headful run You want to watch the page while learning or debugging. Requires a display environment where a visible browser can open.

The official supported-browser table pairs Puppeteer releases with browser versions. For example, the documentation researched for this guide lists Puppeteer 25.12.0 with Chrome for Testing 154.0.8037.57. Check the current table before pinning or substituting a browser because the mapping changes by release. [Supported browsers]

Use the bundled browser or manage one yourself

For a first run, keep the default puppeteer.launch() so Puppeteer uses the browser it installed. If you have a specific reason to use a managed browser, Puppeteer’s launch API supports explicit browser configuration such as executablePath or channel. Confirm your Puppeteer and browser versions against the compatibility guidance first. [Launch API]

puppeteer-core is appropriate when another system owns browser installation or when connecting to a remote browser. It is not the easiest first-run package: without an available browser configuration, launch cannot succeed. [Installation guide]

Show the browser window

Headless is the default. Set headless: false to see the browser while it runs:

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

This option is useful for learning and visual debugging. A headful browser needs a graphical display; a headless setup may be more suitable for a server or CI environment. Puppeteer also documents headless: 'shell', which selects the separate chrome-headless-shell binary. It may be a more performant automation option when full Chrome behavior is unnecessary; use it only when its behavior suits your task. [Headless modes]

5. Configure navigation and page work

The smallest script can rely on defaults. For real automation, choose navigation and waiting behavior deliberately:

  • Navigation: page.goto(url) returns a navigation response when available. If your task needs a particular readiness point, Puppeteer navigation options support lifecycle conditions such as waitUntil. A page can continue making background requests after it appears usable, so do not wait for network silence unless the task needs it.
  • Viewport: call page.setViewport({ width, height }) before navigation when the page’s responsive layout or screenshots depend on the viewport.
  • Interaction: use locators for finding and acting on page elements. Wait for the element or resulting state you need rather than assuming a fixed delay will fit every page.
  • Page content: use page APIs or locator mapping to read the specific title, text, attribute, or value required. Keep browser-side evaluation focused on data that must be read from the page.
  • Cleanup: close pages or the browser in a finally block so failures do not leave browser processes running.

See the official API for the complete set of launch and navigation options; their exact behavior and availability can change with the release. [Launch API, Getting started]

6. Troubleshoot common first-run errors

Symptom Likely cause What to do
Could not find Chrome (ver. …) A package-manager policy blocked Puppeteer’s install script, or the browser download did not complete. Run npx puppeteer browsers install to install the browser explicitly, then retry. Alternatively, allow the Puppeteer install script under your package-manager policy. [Installation troubleshooting]
The browser fails to start on Linux Required system libraries or other OS dependencies may be missing. Use Puppeteer’s Linux troubleshooting guidance for your distribution. The browser management docs describe installing Chrome dependencies with a command for Ubuntu/Debian that requires root privileges; do not apply that distro-specific procedure to other Linux distributions without checking their guidance. [Puppeteer FAQ, Browser management]
A system Chrome launch fails or behaves differently The browser version may not match the Puppeteer release. Return to the bundled browser to establish a compatible baseline, or check the supported-browser table before selecting another version. [Supported browsers, Launch API]
No browser window appears Headless mode is the default. Launch with { headless: false } and ensure the machine has a graphical display. [Headless modes]
page.goto() rejects or does not reach the page you expect The URL may be invalid or unreachable, navigation may time out, or the destination may redirect or require authentication. Check the URL and network access, inspect the thrown error and returned response where available, and choose a navigation timeout or lifecycle condition that matches the task. Do not treat a successful navigation event as proof that the page’s application content is ready; wait for the specific element or state you need.
A locator never resolves The selector does not match, the element is inside a different frame or shadow root, or the page has not reached the state you expect. Inspect the live page and selector, account for frames or shadow DOM where relevant, and wait for the actual target state rather than increasing a blind delay.

7. Performance, reliability, and cost

A local Puppeteer script has no per-screenshot API charge, but it uses compute, memory, disk, and browser-download bandwidth on the machine running it. The downloaded browser binaries are the largest first-run setup cost. Reuse a browser process for a batch of pages when appropriate, but close pages and the browser reliably and watch resource use for long jobs.

For repeatable runs, pin the Puppeteer dependency, use its paired browser, and make the runtime environment’s dependencies explicit. If you substitute a system browser, you add a compatibility variable. Navigation and selectors can also fail when sites are slow, change their markup, show consent dialogs, or require a logged-in session; build waits and error handling around the actual page state your task needs.

Puppeteer automates Chrome through CDP by default. Its FAQ describes production-ready WebDriver BiDi support for Chrome and Firefox from v23.0.0 onward, with differences in supported APIs. If cross-browser automation matters, check the current protocol and API support before choosing a workflow. [Puppeteer FAQ]

Or skip the browser setup

If your task is to capture a webpage rather than automate a browser interaction, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. Its one-call API returns a PNG, JPEG, WebP, or PDF; see the ScreenshotNeo API documentation.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://developer.chrome.com/"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://developer.chrome.com/'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie and consent banners are accepted before capture; more than 60 known consent platforms, newsletter popups, and chat widgets can be removed. Each step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and whether it was billed.
  • An 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 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.

Frequently asked questions

How do I install Puppeteer?

Run npm install puppeteer in your project to install the package and its compatible browser. If install scripts are blocked, install the browser explicitly with npx puppeteer browsers install. [Installation guide]

How do I launch Chrome with Puppeteer?

Import puppeteer and call await puppeteer.launch(). For the compatible default, let Puppeteer use its bundled browser. [Getting started guide]

Why does Puppeteer say it could not find Chrome?

The install process may not have run Puppeteer’s browser download. Run npx puppeteer browsers install and check package-manager install-script policy. [Installation troubleshooting]

Does Puppeteer open a visible browser by default?

No. Headless is the default. Use puppeteer.launch({ headless: false }) to show a browser window on a machine with a display. [Headless modes]