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.

Playwright runs headless by default. When it does not, check four layers in order: install the matching browser, install operating-system libraries, verify launch settings, and inspect the environment that actually runs the test. In Linux CI or a container, the usual fix is npx playwright install --with-deps. If you intentionally run headed on Linux, provide Xvfb. Turn on DEBUG=pw:browser and DEBUG=pw:api before changing application code.

Use this repair sequence first

  1. Confirm the mode. Keep headless: true (or omit the option) for a display-free CI job. Use headless: false only when you deliberately need a visible browser.
  2. Install browsers in the execution environment. Run npx playwright install after installing or upgrading Playwright. On Linux CI, use npx playwright install --with-deps.
  3. Check the selected artifact. Default Chromium headless uses Playwright’s separate headless shell. A channel: 'chromium' launch uses the full Chromium browser and therefore needs that browser installed.
  4. Remove unverified custom paths. Diagnose with Playwright’s bundled browser before using executablePath or a system Chrome channel.
  5. Read the first launch error. Set DEBUG=pw:browser for browser-process details and DEBUG=pw:api for API-level logs.

This order distinguishes a missing executable from a missing shared library, a display problem, a forced headed setting, or a browser that exits immediately.

Headless and headed are different environments

Headless is the default

Playwright launches browsers in headless mode unless you request otherwise. A basic launch should not need a graphical desktop:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
  await browser.close();
})();

Omitting the option is also valid, but stating headless: true makes an inherited configuration easier to audit.

Headed mode needs a display on Linux

For debugging, you can launch with headless: false and optionally add slowMo so actions are observable. On a Linux agent without a desktop, headed execution requires Xvfb:

xvfb-run npx playwright test

Use that wrapper only when headed execution is intentional. If a supposedly headless job reports a display error, inspect the test configuration, project settings, helper functions, and CI wrapper for a forced headless: false value.

Install the browser and Linux dependencies in the right place

Local machine

After installing or upgrading the Playwright package, install its browser binaries:

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

The command must be run for the same project and package version that executes your tests. Installing a browser on a developer laptop does not make it available inside a separate CI runner or container.

Linux CI runner

Use the combined command so the browser and required system libraries are installed together:

npx playwright install --with-deps

Place this step in the job that runs Playwright, after dependencies are installed and before tests start. A cache containing an old browser can become invalid after a Playwright upgrade; rerun the install command rather than assuming the cache is compatible.

Docker

If maintaining operating-system packages is inconvenient, use the official Playwright Docker image as the job’s base environment. It provides a prebuilt environment intended for browser automation. Whichever image you choose, run the test inside that image; installing browsers on the host does not repair a container whose filesystem lacks them.

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

Choose the correct Chromium artifact

Playwright ships a regular Chromium build for headed operations and a separate Chromium headless shell for the default headless path. This distinction matters when you minimize an installation.

Default headless launch

A normal Chromium launch uses the headless shell that Playwright installs for default headless operation. A headless-shell-only installation is documented with:

npx playwright install --with-deps --only-shell

Use this only when your tests do not need the regular Chromium build for headed work or another launch path.

The chromium channel

If you launch with channel: 'chromium', you opt into the newer headless mode backed by the full Chromium 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.
const browser = await chromium.launch({
  channel: 'chromium',
  headless: true
});

That setting changes the required artifact. An installation containing only the headless shell is not the same as an installation containing the full Chromium browser. Install the full browser with the standard Playwright install command, or remove the channel while diagnosing.

Eliminate executable-path and channel mismatches

Playwright works best with its bundled Chromium. A custom executablePath can point to a stale system browser, a path that exists only on a developer machine, or a relative path resolved from an unexpected working directory. A channel that was never installed creates the same symptom as a missing binary.

Start with the supported baseline:

const browser = await chromium.launch({ headless: true });

Only after that succeeds should you restore a custom path or channel. If you must use one, verify it in the same runtime and print the resolved value before launch. Keep the path absolute and make its availability part of the CI image or setup step. Playwright warns that executablePath should be used with extreme caution because an arbitrary browser is not guaranteed to match the bundled version.

Turn on evidence before changing code

Browser-process diagnostics

To inspect executable, process, and early-exit failures:

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.
DEBUG=pw:browser npx playwright test

API diagnostics

For verbose Playwright API calls and configuration flow:

DEBUG=pw:api npx playwright test

On PowerShell, set the variable for the command’s process:

$env:DEBUG = 'pw:browser'
npx playwright test

Repeat with pw:api when you need API-level output. Preserve the first launch error. Later timeout messages often conceal the original cause.

Match the remedy to the runtime

Situation Mode Browser/dependency action Display action
Developer machine Default headless npx playwright install None
Linux CI runner Default headless npx playwright install --with-deps None
Linux CI runner Intentional headed Install browser and dependencies Run through xvfb-run
Container Headless or headed Use the official Playwright Docker image, or install both browser and OS libraries in the image Xvfb is still required for headed Linux execution
Minimal Chromium setup Default headless only npx playwright install --with-deps --only-shell None
Full-browser headless channel: 'chromium' Install the full Chromium browser, not only the headless shell None for headless

Common errors and precise fixes

browserType.launch: Executable doesn't exist

Cause: The browser was not installed in this runtime, the Playwright version changed, or the selected channel requires a different artifact.

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

Fix: Run npx playwright install; on Linux CI run npx playwright install --with-deps. Remove executablePath and channel temporarily. If you use --only-shell, do not launch with channel: 'chromium' unless the full browser is also installed.

Failed to launch browser process with a shared-library message

Cause: The browser binary exists, but the Linux runtime is missing an operating-system dependency.

Fix: Reinstall with npx playwright install --with-deps, or move the job to the official Playwright Docker image. Ensure the command runs inside the same container or runner that executes the tests.

DISPLAY or X-server errors

Cause: The job is headed even though the machine has no graphical display.

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

Fix: Keep headless: true for CI, then find the setting or wrapper forcing headed mode. If headed behavior is required, install and invoke Xvfb with xvfb-run npx playwright test.

The script works locally but not in CI

Cause: Local browser binaries, libraries, environment variables, or a custom path are absent from CI.

Fix: Add the browser installation to the CI job, use --with-deps on Linux, and test the bundled browser without a custom executable path. Enable both debug namespaces and compare the first launch error rather than the final test timeout.

The browser starts and exits immediately

Cause: A channel or executable path points to an incompatible browser, or the runtime is rejecting a required dependency.

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

Fix: Return to chromium.launch({ headless: true }), reinstall the matching browser, and use DEBUG=pw:browser. Restore custom settings one at a time after the baseline works.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Reliability, performance, and cost considerations

Keep installation deterministic

Install browsers as part of the same reproducible job or container image that runs tests. Do not depend on a developer’s global Chrome installation. Re-run installation when upgrading Playwright, and treat browser caches as an optimization rather than the source of truth.

Use the smallest valid artifact

If every run is default headless and no headed project or chromium channel is used, the headless-shell-only option can reduce the installed browser set. If projects share headed and headless modes, install the regular browser instead of creating a setup that passes one project and fails another.

Separate display troubleshooting from browser troubleshooting

Headless failures do not require Xvfb. Adding Xvfb to every job can hide the real issue and adds another moving part. First prove the default headless launch; add Xvfb only for an intentional headed run.

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

What costs time

Browser downloads and Linux dependency installation add setup time, while a missing executable or library causes immediate failure. A deterministic install step usually costs less overall than repeated retries against a partially configured runner.

Or skip the browser setup

For a one-off website image or an automated capture service, ScreenshotNeo accepts one GET request and returns a PNG, JPEG, WebP, or PDF. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the complete parameter reference in the ScreenshotNeo documentation. The following calls use the supplied API format:

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

ScreenshotNeo includes full-page captures with lazy images loaded, CSS-selector element captures, device presets and custom viewports, retina scale, dark mode, PDFs with paper size, margins, orientation and page ranges, custom CSS and JavaScript, clicks before capture, selector hiding, selector or network-idle waits, request and resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs. Every feature is on every plan. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, with yearly billing giving two months free.

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

Create a free ScreenshotNeo account to get 1,000 screenshots a month without a card.

Frequently Asked Questions

Should browser installation be a separate CI job?

It can be a separate setup step, but it must run in the same runner or container filesystem used by the Playwright tests. A browser installed on another machine is not available to the test process.

When is --only-shell the wrong choice?

It is wrong when a project needs headed Chromium or launches with channel: 'chromium', because those paths require the full Chromium browser artifact.

What should I keep from a failed diagnostic run?

Keep the first pw:browser or pw:api launch error together with the mode, channel, executable setting, and runtime type. That combination identifies which layer needs correction.

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

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.