Playwright CLAUDE.md AGENTS.md CI/CD Testing AI Coding 2026

Playwright Now Installs Two Chromium Browsers by Default. Your AI Agent's CLAUDE.md Doesn't Know About --only-shell (2026)

The Prompt Shelf ·

npx playwright install chromium is one of the most-copied commands in web development — it’s in every Playwright tutorial, every Docker CLAUDE.md example, and almost certainly in your AI coding agent’s training data. What most of those sources don’t mention: since Playwright switched Chromium to Chrome for Testing in v1.57 (November 2025), that command downloads two separate browser builds — a full “headed” Chrome for Testing binary and a standalone chromium-headless-shell — even if your CI pipeline or agent sandbox only ever runs headless. There’s a flag that stops this, --only-shell, and it’s barely documented outside Playwright’s own site. We verified the default behavior directly in playwright-core’s shipped browsers.json, not just the docs, and measured the actual byte cost.

Browse more real-world CLAUDE.md and AGENTS.md examples in our gallery.

What playwright-core Actually Ships as “Default”

The install behavior isn’t buried in application logic — it’s declared as data, in browsers.json, the file playwright-core ships to decide what npx playwright install downloads with no arguments:

{
  "name": "chromium",
  "revision": "1243",
  "installByDefault": true,
  "browserVersion": "153.0.8010.12",
  "title": "Chrome for Testing"
},
{
  "name": "chromium-headless-shell",
  "revision": "1243",
  "installByDefault": true,
  "browserVersion": "153.0.8010.12",
  "title": "Chrome Headless Shell"
}

Both entries — the pinned versions shipped with playwright@1.63.0, the version current as of this writing — carry "installByDefault": true. That’s the whole mechanism. Run npx playwright install or npx playwright install chromium with no flags, and Playwright’s registry code (packages/playwright-core/src/server/registry/index.ts) walks every executable marked installByDefault and pulls it down, full Chrome build and headless shell both, unless you tell it otherwise:

// _defaultBrowsersToInstall(), registry/index.ts
private _defaultBrowsersToInstall(options: { shell?: 'no' | 'only' }): Executable[] {
  let executables = this.defaultExecutables();
  if (options.shell === 'no')
    executables = executables.filter(e => e.name !== 'chromium-headless-shell');
  if (options.shell === 'only')
    executables = executables.filter(e => e.name !== 'chromium');
  return executables;
}

options.shell only gets set to 'only' or 'no' when you explicitly pass --only-shell or --no-shell on the CLI. Leave both off — which is what almost every copy-pasted install command does — and you get both binaries.

The Actual Byte Cost

We checked the Chrome for Testing storage bucket directly for the Linux x64 builds pinned to playwright@1.63.0 (revision 1243, Chrome 153.0.8010.12):

BuildCompressed download
chrome-linux64.zip (full, headed-capable)~186.7 MB
chrome-headless-shell-linux64.zip (shell only)~114.3 MB
Both, default behavior~301 MB

If your test suite, CI runner, or agent sandbox never launches Chromium in headed mode — the overwhelming majority of CI and containerized-agent setups don’t — the full chrome-linux64.zip is dead weight. Passing --only-shell cuts the Chromium install from ~301MB to ~114MB, a 62% reduction, before you even get to Firefox or WebKit.

That’s not a rounding error in a Docker build. It’s extra time on every docker build --no-cache, every fresh CI runner with a cold cache, and every ephemeral sandbox an AI coding agent spins up to run a test suite once and throw away.

Why AI Agents Default to the Wrong Command

Ask Claude Code, Cursor, or Copilot to “set up Playwright for CI” and the command it reaches for is almost always some variant of:

# What agents write by default — installs both builds
npx playwright install --with-deps

This isn’t a hallucination — it’s the exact command shown on Playwright’s own CI documentation page, with no --only-shell in sight. The official Docker guide doesn’t mention the flag either. Every pre-2025-11 tutorial, Stack Overflow answer, and blog post an agent’s training data draws from predates the Chrome for Testing split entirely, back when chromium meant one download. The flag exists — Playwright’s browsers documentation recommends it explicitly for CI — but it’s opt-in, and nothing in the more commonly copied surfaces (the CI guide, most Docker examples) points an agent toward it.

None of this is a bug. It’s a case where the ecosystem’s default behavior changed, the flag to correct it shipped alongside that change, and the majority of reference material an agent learns from simply hasn’t caught up.

CLAUDE.md Rule to Add

## Playwright Browser Installation

- This project runs Playwright headless only — no headed/UI test runs in CI or local dev.
- Always install browsers with `npx playwright install --with-deps --only-shell chromium`.
- Never suggest plain `npx playwright install` or `npx playwright install chromium` without `--only-shell` — it downloads an unused ~187MB headed Chrome build on every fresh environment.
- If a task genuinely requires headed mode (visual debugging, `--headed` flag, `page.pause()`), install the full build explicitly for that one environment: `npx playwright install chromium` (no `--only-shell`) — do not remove `--only-shell` from the CI/Dockerfile install step to do this.
- Firefox and WebKit follow the same `installByDefault: true` pattern but don't ship a shell-only variant — `--only-shell` only affects Chromium.

The last line matters: --only-shell is Chromium-specific. If your CLAUDE.md also installs Firefox or WebKit for cross-browser testing, those still download their single default build — there’s no equivalent flag to shrink them further, because they never split into headed/headless builds the way Chromium did.

Dockerfile and CI Examples

GitHub Actions:

- name: Install Playwright browsers
  run: npx playwright install --with-deps --only-shell chromium

Dockerfile (self-managed image instead of mcr.microsoft.com/playwright):

FROM node:22-slim
RUN npx -y playwright@1.63.0 install --with-deps --only-shell chromium

If you’re on Microsoft’s official mcr.microsoft.com/playwright base image, this doesn’t help — the prebuilt image ships every default browser already, --only-shell only changes what gets downloaded when you run install yourself. The savings apply when your agent or CI pipeline is installing browsers fresh, not when it’s pulling the prebuilt image.

Check the Package, Cache and Launch Mode Before Reinstalling

Correction — October 14, 2026: An earlier version of this section said that finding both Chromium builds in the cache meant --only-shell had not been applied. That conclusion was too strong. A full browser left by a previous installation can coexist with a shell-only installation. Cache contents alone do not prove which executable a particular test will request, or that the test can launch it.

The official browser guide distinguishes default headless shell from the chromium channel and explains that each Playwright version needs specific browser binaries. Check all three inputs: the package actually running the test, the cache location visible to that process, and its launch options.

What We Actually Ran

We tested two already-installed Node.js Playwright packages on macOS arm64 on October 14, 2026. We created temporary cache directories; the shell-only directory referenced an existing revision 1208 binary. We did not download browsers, change the shared cache, use credentials or visit an external website. The successful case opened a local HTML page and checked its title.

Package usedTemporary cacheLaunch optionsActual result
1.58.2Emptyheadless: true, no channelMissing chromium_headless_shell-1208 executable
1.58.2Existing shell 1208 onlyheadless: true, no channelLocal page opened successfully
1.58.2Same shell 1208 onlyheadless: true, channel: 'chromium'Missing full chromium-1208 executable
1.64.0-alpha-1790635538000Same shell 1208 onlyheadless: true, no channelMissing chromium_headless_shell-1247 executable

The alpha package was already present on the test machine; it is not a recommendation or a claim about the current stable version. This experiment demonstrates executable selection in these two packages. It does not establish behavior for every release, Python, Linux or your CI image. The cache references were a disposable test arrangement, not a repair technique.

The useful distinction is that headless: true does not by itself mean “uses the headless shell.” In our 1.58.2 test, specifying the chromium channel selected the full browser even though the launch was headless. Also, a shell suitable for one package revision did not satisfy the other package.

Read-Only Checks for an Existing Node.js Project

From the project that runs the tests, use its already-installed Playwright CLI. For a conventional npm layout where this file exists:

node ./node_modules/playwright/cli.js --version
node ./node_modules/playwright/cli.js install --dry-run --only-shell chromium
node ./node_modules/playwright/cli.js install --list

These commands inspect the installed package, the proposed download targets and the visible cache. --dry-run does not install anything or prove that a browser launches. --list may include browsers retained for other projects or package versions. If this local CLI file is absent, first identify the dependency and package-manager layout your project actually uses; do not substitute an unpinned npx download as a diagnostic step.

Read the cache override without printing the rest of your environment:

node -e 'console.log(process.env.PLAYWRIGHT_BROWSERS_PATH ?? "(platform default)")'

Compare that output and the dry-run target with the exact executable path in the failed test’s error, then inspect the test’s channel and headless settings. Run these checks in the same environment that runs the test: a different shell, container or CI job can see a different cache override. A file existing at some other Chromium path is not proof that this request is satisfied.

For default headless shell, investigate the requested shell revision. For channel: 'chromium', investigate the requested full Chromium revision. Decide whether the intended test mode or the project’s normal browser installation needs correction only after that comparison. Do not rename cache directories or force an arbitrary executablePath to conceal a revision mismatch. If the requested executable exists but launch still fails, keep the actual launch error: missing-executable diagnosis does not explain every runtime failure.


None of this requires changing test code, your Playwright config, or your CI provider. It’s one flag, in one install command, that most tutorials — and by extension most AI coding agents — never picked up because it postdates the material they learned from. Add the rule once and every fresh environment your agent provisions gets ~187MB lighter.

Browse working CLAUDE.md and AGENTS.md examples with CI and testing sections from real projects in our gallery.


FAQ

Does --only-shell break headed test runs or page.pause() debugging? Yes, if applied globally. chromium-headless-shell cannot run in headed mode. Use --only-shell for CI and containerized/headless agent environments, and keep a separate local dev environment (or a one-off npx playwright install chromium without the flag) for anyone who needs --headed or page.pause().

Does this affect Firefox or WebKit installs too? No. Only Chromium split into a separate headed build and headless shell after the Chrome for Testing switch. Firefox and WebKit each still ship as a single default download — --only-shell has no effect on them.

Is the full Chrome for Testing build actually unused if I never set --only-shell? In a headless-only CI or agent sandbox, yes — Playwright launches chromium-headless-shell automatically for headless runs unless you explicitly request the chromium channel. The full build sits on disk unused unless something in your config or a manual --headed run calls for it.

Why doesn’t Playwright just make --only-shell the default for CI? Playwright can’t reliably detect “CI-only, headless-only” at install time — some CI jobs run headed (rare but real, e.g. video recording setups), and changing the default would silently break them. --only-shell stays opt-in so the choice belongs to the project.

Does mcr.microsoft.com/playwright’s Docker image already do this for me? No — Microsoft’s official Playwright Docker image ships every default browser preinstalled, headed Chrome build included, to support any use case out of the box. --only-shell only changes the size of what you download during a fresh npx playwright install — it doesn’t shrink the prebuilt image.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules