DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
browser automation

How to Run a Puppeteer Script (Node.js, Chrome Setup, Headless Mode, and Troubleshooting)

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

To run a Puppeteer script, install a supported Node.js release, install the puppeteer package, save your code in a JavaScript module, and execute it with node. Puppeteer normally downloads a compatible Chrome for Testing browser for you, launches headless Chrome, opens a page, performs actions, and then closes the browser. The complete quick start is:

mkdir puppeteer-demo
cd puppeteer-demo
npm init -y
npm i puppeteer

Create example.mjs with a launch, navigation, and cleanup block, then run node example.mjs. The sections below cover the exact setup, visible and headless runs, server use, alternatives, and failures such as missing Chrome or a hanging page.

What you need before running Puppeteer

  • Node.js: Puppeteer’s current system-requirements page lists Node 22.12 or newer. Check your version with node --version and install a current LTS release if it is older.
  • Operating-system libraries: Linux installations need the libraries listed in Puppeteer’s system requirements. A successful npm install does not guarantee that Chrome can start if a shared library is absent.
  • A project directory: Keeping the package and script together makes browser downloads and module resolution predictable.

Puppeteer is a JavaScript library that controls Chrome or Firefox through the DevTools Protocol or WebDriver BiDi. Its documented workflow is to launch or connect to a browser, create pages, and manipulate them with Puppeteer’s API (Puppeteer Getting started, documentation version 25.12.0 shown in the 2026 snapshot).

Install Puppeteer in a new project

  1. Create and enter a project

    mkdir puppeteer-demo
    cd puppeteer-demo
    npm init -y
    
  2. Choose the package

    For the normal local workflow, install puppeteer:

    npm i puppeteer

    The package installation downloads a compatible Chrome for Testing browser. If your package manager or security policy blocks install scripts, that download may not happen; use the current Puppeteer installation guide for the supported browser-install procedure.

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

    Install puppeteer-core only when you intentionally manage Chrome yourself or connect to an existing browser:

    npm i puppeteer-core

    puppeteer-core does not download Chrome. You must supply an executable path or connection details, so it requires more configuration.

Package Who manages Chrome? Best use Configuration
puppeteer Puppeteer downloads a compatible browser Local scripts and most new projects Lowest
puppeteer-core You or an infrastructure provider Existing, pinned, system, or remote browsers Provide executable or endpoint

Write and run a minimal script

Save this as example.mjs in the project directory:

import puppeteer from 'puppeteer';

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

Run it from that directory:

node example.mjs

You should see the page title in your terminal. The try/finally block matters: navigation, selectors, or evaluation can throw, and browser.close() still runs instead of leaving Chrome processes behind. Add a timeout when a site may respond slowly:

await page.goto('https://example.com', {
  waitUntil: 'networkidle2',
  timeout: 60_000
});

Use a CommonJS file only when your project is configured for it. Depending on your package version and project settings, that means a suitable require form or setting "type": "module" in package.json; do not mix module systems accidentally.

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

Headless, headful, and shell modes

Puppeteer runs headless by default, so no browser window appears. That is normal for automation and CI. To watch the browser while developing:

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

slowMo inserts a delay between operations, making clicks and navigations easier to observe. Remove it for normal runs.

Puppeteer also documents headless: 'shell', which uses Chrome’s separate headless shell. It can be faster for automation but does not provide the complete behavior of regular Chrome. Choose it only when your script does not depend on features unavailable in that shell. See Headless mode documentation for the distinctions.

Useful browser and page patterns

Set a viewport and capture a screenshot

const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'example.png', fullPage: true });

Interact with a form

await page.goto('https://example.com/login');
await page.locator('input[name="email"]').fill('[email protected]');
await page.locator('input[name="password"]').fill(process.env.PASSWORD ?? '');
await page.locator('button[type="submit"]').click();
await page.waitForSelector('.dashboard');

Keep credentials in environment variables rather than source files, and avoid logging page content that may contain personal or secret data.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Wait for the condition you actually need

  • Use waitUntil: 'domcontentloaded' when the initial HTML is enough.
  • Use networkidle2 for pages that finish loading after a small amount of network activity.
  • Use waitForSelector for a specific component. A selector wait is usually more reliable than an arbitrary long sleep.

Debug a script by layer

Browser startup, Node-side Puppeteer code, and code running inside the page are separate failure surfaces. Make the browser visible first, then add targeted logs.

See messages printed by the page

page.on('console', message => {
  console.log(`[page:${message.type()}] ${message.text()}`);
});

Forward browser-process output

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

dumpio: true forwards browser output to the Node process. Treat verbose output as potentially sensitive because URLs, headers, or page data may appear in logs.

Investigate a pending protocol call

If an API call appears stuck, consult Puppeteer’s debugging guide for pending-call diagnostics and protocol logging. Enable verbose logs only temporarily and protect the resulting files; they can contain sensitive information.

Run Puppeteer on Linux, a server, or CI

Puppeteer itself is a library, not a hosting service. On a server or CI runner, install Node and the Linux packages listed on the system requirements page, then install dependencies with the same package-lock file used locally. The downloaded browser must be available to the account running the job, and the process needs permission to create its temporary profile.

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

Start with ordinary headless mode. If a restricted container prevents Chrome from starting, do not blindly add unsafe flags; first compare the container’s libraries, user permissions, shared-memory configuration, and sandbox policy with the deployment environment. Pin your Node and package versions, set explicit navigation and selector timeouts, and always close the browser in a finally block.

Connect to an existing browser

The specialized “running Puppeteer in the browser” scenario cannot launch or download Chrome through Node APIs. It connects to an already running browser through a WebSocket endpoint. Use this only when your platform supplies that browser; most local scripts should use puppeteer.launch() instead. See Running Puppeteer in the browser.

Common errors and fixes

Symptom Likely cause Fix
Could not find Chrome or a missing executable The browser download was skipped, or you installed puppeteer-core Use puppeteer for the managed-browser path, allow its install script, or configure the executable/endpoint explicitly with puppeteer-core. Follow the current installation guide.
Chrome fails immediately on Linux Missing shared libraries, permissions, or an incompatible runtime Compare the machine’s packages with Puppeteer’s system-requirements list; run under a permitted user and inspect browser output with dumpio.
No window appears Headless mode is the default Use headless: false while debugging, then return to headless mode for automation.
The script hangs at navigation The site keeps connections open, waits for a resource, or the default timeout is unsuitable Set an explicit timeout, choose an appropriate waitUntil value, and wait for the specific selector your task requires.
Page logs do not appear in Node Browser console messages are not forwarded automatically Register a page.on('console', ...) listener before navigation.
Browser processes remain after an error No cleanup path Wrap work in try/finally and close the browser in finally.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a clean website image rather than browser automation, ScreenshotNeo provides a website screenshot API and MCP server. Its service accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers.

One GET request returns PNG, JPEG, WebP, or PDF. The API supports full-page captures with lazy images, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, PDF paper and page settings, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage data, and an OpenAPI specification. Its parameter names are compatible with those used by many screenshot APIs.

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

Use the API documentation at screenshotneo.com/docs/ for the full option list. 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)
open("shot.webp", "wb").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}`);

An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.

FAQ

Does Puppeteer run without Chrome installed system-wide?

Yes, when you install the standard puppeteer package and its browser download completes. puppeteer-core assumes you provide the browser.

Can I use Firefox?

Puppeteer describes support for controlling Chrome or Firefox, but browser-specific behavior and setup can differ. Verify the current compatibility notes before switching.

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

Should production jobs use headless mode?

Usually. Headless mode avoids a display requirement; use headful mode temporarily when diagnosing visual or interaction problems.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.