How to Launch a Browser with Puppeteer
Launch Puppeteer in headless or visible mode, choose the right browser package, configure options, and fix common startup errors.
To launch a browser with Puppeteer, install the puppeteer package and call puppeteer.launch(). It launches headless Chrome by default. Create a page, navigate to a URL, and close the browser when finished:
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();
}
This guide covers package choice, launch modes, browser selection, useful options, cleanup, and common launch failures.
1. Install Puppeteer and choose who manages Chrome
Use puppeteer when you want Puppeteer to install a compatible browser. Its installation downloads Chrome for Testing and chrome-headless-shell. Use puppeteer-core when you manage the browser yourself or connect to a remote browser; it does not download Chrome.
npm install puppeteer
If you choose puppeteer-core, provide a browser executable path or a Chrome channel when launching. Puppeteer documents compatibility with the Chrome for Testing version it downloads by default; compatibility with arbitrary Chrome versions is not guaranteed. See the official installation guide and launch API.
If a package manager blocks install scripts, the browser download may not happen. The installation guide explains how to install the browser manually with the Puppeteer browsers command or allow the package installation script.
2. Launch in the mode you need
Headless (default)
const browser = await puppeteer.launch();
Headless mode runs without displaying a browser window and is the default.
Visible Chrome
const browser = await puppeteer.launch({ headless: false });
Use this when you need to watch the browser, debug navigation, or interact with the window yourself.
Chrome Headless Shell
const browser = await puppeteer.launch({ headless: 'shell' });
This selects chrome-headless-shell, the separate browser binary associated with the old headless mode. It does not completely match regular Chrome, so choose it only when its browser differences suit your automation. Puppeteer’s guide describes it as a potentially more performant option when the full feature set is unnecessary. See headless modes.
3. Select a system-installed browser
With the higher-level puppeteer package, you can select a locally installed Chrome channel or point to a specific executable:
const browser = await puppeteer.launch({
channel: 'chrome',
headless: true,
});
const browser = await puppeteer.launch({
executablePath: '/path/to/chrome',
headless: true,
});
Channel values and browser locations depend on the platform and installation. Using another browser executable is your responsibility: Puppeteer guarantees compatibility with its bundled browser, not every external version.
For puppeteer-core, a browser path or channel is required:
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.launch({
executablePath: '/path/to/chrome',
});
Alternatively, configure channel when the desired Chrome release channel is installed. Consult the launch API for the current options.
4. Configure launch options
Launch options let you choose the browser, mode, startup timeout, process output, profile directory, and command-line arguments. Commonly useful options include:
| Option | Purpose | Notes |
|---|---|---|
browser |
Select the browser type. | See the API for supported values. |
channel |
Select an installed browser release channel. | Available channels depend on the system. |
executablePath |
Use a specific browser executable. | Check the path and compatibility yourself. |
headless |
Choose default headless, visible (false), or 'shell'. |
DevTools forces headful mode. |
args |
Pass arguments to the browser process. | Avoid removing Puppeteer’s defaults casually. |
env |
Set environment variables for the browser process. | Useful for controlling the child process environment. |
timeout |
Set the maximum browser startup wait. | The documented default is 30,000 ms. |
dumpio |
Pipe browser stdout and stderr to Node. | Useful for diagnosing startup problems. |
userDataDir |
Choose a browser profile directory. | Use separate directories for concurrent browser instances. |
devtools |
Open DevTools. | Forces headful mode. |
Example with a longer startup timeout and browser diagnostics:
const browser = await puppeteer.launch({
timeout: 60_000,
dumpio: true,
});
Only change command-line arguments when you understand what Puppeteer supplies. The API specifically cautions that overriding default arguments can break assumptions the library relies on.
5. Use a reliable launch and cleanup pattern
Close the browser even if navigation or page work throws an error. A finally block makes cleanup predictable:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: true,
timeout: 30_000,
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 30_000,
});
console.log(await page.title());
} finally {
await browser.close();
}
The navigation settings above govern page loading; they are separate from the launch timeout, which governs browser startup. If the browser is shared across multiple pages, close each page when its work is done and close the browser when the process no longer needs it.
6. Troubleshoot common launch failures
| Error or symptom | Likely cause | What to do |
|---|---|---|
| “Could not find Chrome” | The install script was skipped or the browser download did not complete. | Run the Puppeteer browser installation command manually or allow the package manager’s install script. See the installation guide. |
| Executable path error | executablePath points to a missing or non-executable file. |
Check the actual browser location and permissions, or use an installed supported channel. |
puppeteer-core cannot launch |
No browser was downloaded, and no external browser was configured. | Pass executablePath or channel. |
| Missing shared libraries on Linux | The host lacks operating-system dependencies needed by Chrome. | Check the host’s dependencies. Puppeteer’s installation options document installDeps for Chrome on Debian/Ubuntu; it requires system-level privileges. See browser installation options. |
| Sandbox or permission error | The host’s sandbox configuration or security policy prevents Chrome from starting. | Configure the host and browser sandbox. Puppeteer’s troubleshooting guide describes Windows and Ubuntu/AppArmor cases and strongly discourages running without a sandbox. Do not use --no-sandbox as a routine fix. See troubleshooting. |
| Startup takes too long | Browser startup is slow or blocked by host constraints. | Use dumpio: true to inspect process output and increase the launch timeout only if the environment legitimately needs longer. |
| Unexpected browser behavior | An arbitrary system browser version or headless shell differs from Puppeteer’s expected browser. | Try the bundled Chrome for Testing version, or verify that the chosen mode and browser version support the behavior you need. |
7. Performance, reliability, and cost considerations
- Startup cost: launching a browser process is distinct from opening another page. For repeated work in one process, reuse a browser instance where appropriate, and close it when the process is finished.
- Mode choice: headless mode is the default. Headless shell may suit automation that does not need the full regular Chrome feature set, but browser differences matter.
- Compatibility: the bundled browser is Puppeteer’s supported baseline. External executables can introduce version-specific behavior.
- Failure diagnosis: separate package installation, browser executable, operating-system dependencies, and sandbox policy.
dumpiocan reveal browser process output. - Cost: Puppeteer itself is an open-source Node.js library; operating costs depend on the compute environment and browser workload. Browser downloads consume disk space, and running browser processes consume host resources.
8. Or skip the browser setup
If your goal is a website screenshot rather than browser automation, ScreenshotNeo returns an image or PDF from one API request, without installing or managing a browser process. See the ScreenshotNeo API documentation.
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);
The Node.js example uses Bun to save the response body to a file. In Node.js, you can instead write the bytes with await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()))).
- Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server lets AI agents use
take_screenshot,get_page_info, andcapture_pdf. - The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan.
Start with 1,000 free screenshots a month, no card required.
9. Frequently asked questions
Does Puppeteer launch a browser window by default?
No. The default is headless. Set headless: false to show a regular browser window.
Can Puppeteer launch Firefox?
The launch API includes a browser option. Check the current Puppeteer API and installation documentation for supported browser choices and setup details.
Why use puppeteer-core?
Use it when you supply and manage the browser yourself, such as with a system installation or remote browser setup. It does not download Chrome.
Is --no-sandbox a good fix for launch errors?
No. Puppeteer’s troubleshooting guidance strongly discourages running without the browser sandbox. Fix the host’s sandbox configuration instead.
Is launch timeout the same as page navigation timeout?
No. Launch timeout limits browser startup. Navigation timeout controls how long page navigation waits.


