ScreenshotNeo

BlogHow-to

How to Launch Chrome with Puppeteer

Install Puppeteer, choose the right Chrome mode and executable, and troubleshoot common launch failures with runnable JavaScript examples.

By the ScreenshotNeo team4 October 20268 min read

The standard way to launch Chrome with Puppeteer is to install the puppeteer package and call await puppeteer.launch(). Puppeteer normally downloads a compatible Chrome for Testing browser during installation, and launch defaults to headless mode. If you manage Chrome yourself, specify executablePath or a release channel; with puppeteer-core, one of those is required for a local launch. See the official installation guide and launch options.

1. Install Puppeteer and launch Chrome

Use a current Node.js runtime supported by the Puppeteer version you install. The current system requirements page lists Node.js 22.12 or later; because this can change, check the official system requirements for your version and operating system.

npm install puppeteer

Save this as launch.mjs and run node launch.mjs:

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();
}

This example launches the bundled browser, opens a page, navigates to a placeholder URL, prints its title, and closes Chrome even if navigation or title retrieval fails. launch() returns a promise for a Browser.

2. Pick the package that fits your browser setup

Package / approach Use it when Browser selection
puppeteer You want Puppeteer to download and manage its compatible browser. Usually no path is needed; the matching browser is downloaded during installation.
puppeteer-core You manage browser binaries yourself or connect to a remote browser. For local launch(), provide executablePath or channel. For an already-running remote browser, use connect().
System-installed Chrome Your environment has a centrally installed Chrome or a specific release channel. Pass an absolute executablePath or an available channel. Compatibility with arbitrary Chrome versions is not guaranteed.

The puppeteer package downloads Chrome for Testing and, since Puppeteer v21.6.0, a separate chrome-headless-shell binary. The documented default browser cache location from Puppeteer v19 onward is $HOME/.cache/puppeteer. Use puppeteer-core when download and browser lifecycle are deliberately handled elsewhere. Details are in the installation guide.

3. Choose headless, shell, or visible Chrome

Puppeteer’s documented default is headless: true, which uses the current headless Chrome mode. Use the shell mode when you specifically want the separate legacy headless shell. Use visible mode for interactive debugging or workflows that need a displayed browser.

// Default headless Chrome
const browser = await puppeteer.launch();

// Separate chrome-headless-shell binary
const shellBrowser = await puppeteer.launch({ headless: 'shell' });

// Visible Chrome window
const visibleBrowser = await puppeteer.launch({ headless: false });

These are alternatives; close each browser instance when finished. Shell mode does not fully match regular Chrome behavior, so compare it against regular headless or visible Chrome if a page depends on browser features. The headless modes guide explains the distinction. Setting devtools: true also forces headful mode.

4. Select an installed Chrome executable or channel

When Chrome is installed outside Puppeteer’s browser cache, pass its machine-specific absolute path. There is no universal path: it varies by operating system, package manager, and installation method.

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.launch({
  executablePath: '/absolute/path/to/chrome',
  headless: true,
});
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  await browser.close();
}

If a supported release channel is installed in a standard location, you can choose it instead of a path:

const browser = await puppeteer.launch({
  channel: 'chrome',
  headless: true,
});

Use a channel only where that Chrome channel is installed and discoverable on the host. Puppeteer is guaranteed to work best with its bundled browser; a system Chrome choice gives you control but adds version compatibility risk. The launch API documentation describes the required browser selection for puppeteer-core.

5. Configure launch behavior

launch() accepts options for browser selection, startup arguments, environment variables, profile storage, diagnostics, and startup timeout. Start with defaults, then add only settings your environment needs.

Option Purpose Practical note
headless Choose regular headless, 'shell', or visible mode with false. Defaults to true; devtools: true forces visible mode.
executablePath Choose a specific local browser binary. Use an absolute path valid on that machine.
channel Choose an installed Chrome release channel. The channel must exist on the host.
args Pass command-line arguments to Chrome. Avoid removing or filtering Puppeteer’s default arguments unless you understand the effect.
env Set the child browser process environment. Use it for deliberate environment configuration, not as a substitute for installing dependencies.
timeout Limit how long launch may take, in milliseconds. The documented default is 30,000 ms. Increase only when slow startup is expected.
dumpio Forward browser process stdout and stderr to Node’s process streams. Useful for diagnosing startup errors.
userDataDir Choose a Chrome profile directory. Use an isolated profile for concurrent jobs; do not have multiple browser processes write to one profile.
devtools Open Chrome DevTools. Forces headful mode.

Example combining a longer startup timeout and browser diagnostics:

const browser = await puppeteer.launch({
  timeout: 60_000,
  dumpio: true,
});

Environment-based configuration can be useful in containers or deployment systems. Puppeteer documents PUPPETEER_EXECUTABLE_PATH, PUPPETEER_SKIP_DOWNLOAD, and PUPPETEER_CACHE_DIR. Treat these as configuration alternatives: if you skip the download, you must arrange a compatible browser yourself. See Puppeteer configuration.

6. Connect to a remote browser instead of launching locally

If a browser is already running remotely, use Puppeteer’s connection API rather than starting another local Chrome process. For example, Browserless documents a WebSocket endpoint workflow:

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: process.env.BROWSER_WS_ENDPOINT,
});
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
} finally {
  // Disconnect this client from the remote browser.
  await browser.disconnect();
}

Set BROWSER_WS_ENDPOINT to the endpoint provided by your browser service. Do not hard-code credentials or a private endpoint in source control. Browserless describes this pattern in its Puppeteer connection guide; its platform supports cloud and self-hosted options. Remote browsers reduce local browser installation work but add network latency, endpoint availability, and service configuration to the path.

7. Troubleshoot launch failures

Symptom Likely cause What to check or fix
Could not find Chrome (ver. ...) The browser download did not run, often because install scripts were blocked. Run npx puppeteer browsers install after installation, or configure a valid managed browser path. Check the installation guide.
puppeteer-core fails to find a browser Core does not download Chrome, and local launch has no browser selection. Supply executablePath or channel, or connect to a remote browser with connect().
Linux reports missing shared libraries Chrome’s operating-system dependencies are absent. Use the platform dependency list in Puppeteer troubleshooting; the guide suggests checking unresolved libraries with ldd chrome | grep not.
Chrome exits with a sandbox or namespace error The host may not support Chrome’s sandbox configuration, or security policy such as AppArmor may restrict it. Check host support and the official Linux troubleshooting guidance. Chrome’s sandbox protects the host from untrusted page content. Puppeteer strongly discourages --no-sandbox; treat it only as a risky workaround for content the operator absolutely trusts, not standard setup.
Windows policy or permission errors Browser file permissions or extension policies can conflict with default launch flags. Check downloaded browser permissions and the Windows-specific notes in the troubleshooting guide.
Chrome starts, then launch times out Startup is slower than the configured timeout, or Chrome is blocked by an environment issue. Enable dumpio: true to inspect browser output; verify dependencies and increase timeout only if slow startup is expected.
Installed Chrome behaves differently or fails The browser version may not match the Puppeteer release’s supported browser. Compare the installed version with the supported browser mapping. Prefer the bundled browser when version compatibility matters.

8. Performance, reliability, and cost considerations

  • Browser choice: the browser download takes disk space and installation time, but bundles the version Puppeteer expects. A system browser avoids that download in some deployment flows while making compatibility your responsibility.
  • Headless mode: regular headless is the default. The separate shell mode may suit tasks where performance matters more than complete regular Chrome behavior; validate pages that depend on specific features.
  • Startup: launching a new browser for every small task adds process startup overhead. Reusing a browser process and creating pages for sequential jobs can reduce repeated startup, while isolating profiles and bounding concurrency helps avoid shared state and resource pressure.
  • Reliability: pin compatible Puppeteer dependencies and control browser installation in deployment. Keep browser versions aligned, verify OS libraries in the target image, and use a deliberate timeout. The official supported-browser list is version-specific.
  • Cost: Puppeteer itself is an open-source library, but operating a browser consumes compute, memory, storage, and engineering time. Remote browser services may have their own charges; consult their current terms and pricing before choosing one.

Or skip the browser setup

If your goal is a website screenshot rather than browser automation, ScreenshotNeo provides a screenshot API and MCP server. Its API documentation shows the request options and response details. One GET request can return an image or PDF:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
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)
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 removes cookie and consent banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card required.

Frequently asked questions

Does puppeteer.launch() open a visible window by default?

No. Its documented default is headless mode. Pass headless: false to show a Chrome window.

Can I use Firefox with Puppeteer?

Puppeteer supports browser selection beyond Chrome in its documented browser support, but this guide focuses on Chrome launch. Check the current browser support documentation for the version and setup details.

Should I add --no-sandbox to make launch work?

No, not as routine configuration. First diagnose host sandbox support and permissions. Puppeteer warns against disabling the sandbox because it removes an important layer of protection for the host.

Can I launch system Chrome with the regular puppeteer package?

Yes. Set executablePath or channel; choose puppeteer-core if you want to manage browser installation separately.