Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Puppeteer’s unified Chrome Headless mode: launch with headless: true, or omit the option because true is the current default. Remove explicit --headless=old flags. Choose headless: 'shell' only when you deliberately need the separate chrome-headless-shell implementation.
This migration matters because Chrome 132 stopped launching the old mode. The change is usually limited to launch configuration, but visual differences, extensions, downloads, sandboxing and CI assumptions should be tested before you switch production workloads.
The replacement in one minute
For normal browser automation, use the real Chrome browser in unified Headless mode:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: true,
});
await puppeteer.launch() is equivalent in current Puppeteer because headless: true is the default. Do not add --headless=old to args, environment variables or wrapper scripts.
#1 Best Overall
If you need to preserve the old implementation intentionally, select the named shell mode instead:
const browser = await puppeteer.launch({
headless: 'shell',
});
That option selects chrome-headless-shell, a separate, lighter implementation. It is not the same browser binary as unified Headless Chrome.
What changed in Chrome and Puppeteer
Chrome 132 removed the old command-line mode
Chrome for Developers announced that, starting with Chrome 132, --headless=old no longer starts the legacy implementation. The flag prints an error instead. Both --headless and --headless=new run the new Headless implementation in the regular Chrome binary.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesPuppeteer changed its default earlier
The current Puppeteer headless guide, labeled version 25.12.0, notes that versions before 22 launched old Headless by default. Current Puppeteer maps headless: true to new Headless and documents headless: 'shell' when the standalone shell is required.
Rank #2
What “old Headless” means now
“Old Headless” is no longer a mode of the normal Chrome executable. Its implementation continues as chrome-headless-shell. Treat it as a compatibility choice with a different feature and dependency profile, not as a hidden switch inside current Chrome.
Choose the correct mode
| Puppeteer setting | Implementation | Use it when | Trade-off |
|---|---|---|---|
headless: true or omitted |
Unified Headless in regular Chrome | You need the safest default, browser parity, end-to-end coverage or extension-related behavior | Uses the regular Chrome dependency footprint |
headless: 'shell' |
Standalone chrome-headless-shell |
Your workload benefits from a smaller footprint or potentially faster startup and does not require complete regular-Chrome behavior | Not every regular-Chrome capability or behavior is represented |
headless: false |
Visible, headful Chrome | You are diagnosing rendering, permissions, popups or migration differences interactively | Requires a display environment or a virtual display in CI |
--headless=old |
Removed old Chrome mode | None on Chrome 132 and later | Chrome reports an error instead of launching |
Start with unified Headless unless you have a measured, documented reason to use the shell. If your test depends on extensions, exact headful behavior or broad browser compatibility, unified Headless is the safer target.
Migration procedure
- Find every old-mode reference. Search JavaScript, TypeScript, Dockerfiles, npm scripts, CI YAML, shell scripts and test runners for
--headless=old,headless: 'old'and wrappers that append the flag. - Replace the launch setting. Use
headless: trueor remove the property. Do not carry the obsolete flag inargs. - Keep browser arguments that are unrelated. Options such as proxy settings, download directories, custom user data directories and your CI sandbox configuration are independent of the Headless selection. Review each one rather than deleting all arguments.
- Run a visible comparison. Temporarily launch with
headless: falseand inspect navigation, consent dialogs, viewport sizing, downloads, permissions and extension UI. - Test representative pages. Include client-rendered pages, pages with redirects, iframes, lazy content, authentication, file downloads and any site whose screenshot or PDF output is business-critical.
- Pin and record the browser pair. Record the Puppeteer version and the Chrome executable used in CI so a later browser update can be correlated with a rendering change.
Recommended Puppeteer code
Minimal unified Headless launch
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: true,
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
});
console.log(await page.title());
} finally {
await browser.close();
}
You can shorten the launch to puppeteer.launch() when you want the documented default. Keeping headless: true explicit can make a migration easier to audit.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Deliberate shell compatibility
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: 'shell',
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
} finally {
await browser.close();
}
Use this only after checking that your automation does not depend on regular-Chrome behavior. Keep the choice visible in configuration and document why it exists; otherwise a future maintainer may “upgrade” it back to the default without realizing that the implementation changed.
Headful debugging
const browser = await puppeteer.launch({
headless: false,
});
Headful mode is a diagnostic tool, not a replacement for production Headless. It lets you watch focus changes, permission prompts and layout differences that are difficult to understand from logs alone.
Remove obsolete flags from wrappers and CI
A common failed migration changes the Puppeteer option but leaves the old flag in an argument array:
// Remove this:
args: ['--headless=old']
Also check shell commands that invoke Chrome directly. On Chrome 132 and later, replace --headless=old with --headless, or remove the explicit flag when Puppeteer controls the browser. You may leave --headless=new in a direct Chrome command, but it is redundant because plain --headless now selects the same implementation.
Do not attempt to emulate the removed mode by combining unrelated flags. If you truly require its implementation, use Puppeteer’s headless: 'shell' setting and ensure the corresponding shell binary is available in the environment.
Rank #4
Validate behavior after switching
Rendering and screenshots
- Compare viewport dimensions, device scale factor, fonts and scroll height.
- Wait for the same application readiness signal in both runs. A network-idle event alone may occur before late client rendering.
- Check pages that use WebGL, media, workers, cross-origin iframes or permission APIs.
Extensions and browser integration
Unified Headless is the safer choice for extension-related coverage and parity with headful Chrome. If an extension is central to your test, run that suite against unified Headless and a visible browser before retiring the old configuration.
Downloads, PDFs and authentication
- Verify download paths and file names rather than relying on a visual check.
- Compare PDF page breaks and print CSS if your pipeline generates documents.
- Repeat login, cookie and storage-state tests; a mode change can expose timing assumptions even when the page code is unchanged.
CI reliability
Use the same Chrome channel and Puppeteer package in local and CI runs where possible. Capture the browser stderr output on failure. A message about --headless=old identifies a stale flag; a timeout after the mode change usually points to readiness, sandbox, resource or application timing issues and should be debugged separately.
Troubleshooting common migration failures
| Symptom | Likely cause | Fix |
|---|---|---|
Chrome prints an error mentioning --headless=old |
A wrapper or argument array still passes the removed flag | Delete it, use plain --headless, or select headless: 'shell' deliberately in Puppeteer |
| Pages render differently from the old pipeline | You moved from the shell implementation to regular Chrome, or the old run used different timing | Compare with headless: false, record viewport and user-agent settings, and add an application-specific readiness wait |
| An extension test fails | The test is still targeting a legacy assumption or the wrong browser executable | Run the extension suite with unified Headless and verify the executable and package versions used by CI |
| Startup becomes slower or the image grows | Unified Headless uses the regular Chrome binary and its dependencies | Accept the footprint for browser fidelity, or evaluate headless: 'shell' only for workloads that do not need full Chrome behavior |
| Headful debugging works but Headless times out | Code depends on visible UI timing, a display-only prompt or an unhandled permission state | Make permissions and readiness explicit, then reproduce with a clean Headless profile |
| The shell option cannot start | The required chrome-headless-shell binary is absent or incompatible with the installed Puppeteer setup |
Install the shell binary through your deployment process or return to unified Headless, which uses the regular Chrome binary |
Performance, footprint and maintenance decisions
The shell can be attractive in a constrained container because it is a lighter standalone implementation and may start faster for simple automation. Those benefits are workload-dependent; do not assume a universal speed improvement. Measure your own startup time, memory use and throughput with the same pages and concurrency.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteUnified Headless costs more in dependencies in exchange for closer parity with normal Chrome. That trade-off is usually worthwhile for end-to-end tests, complex applications, extension coverage and screenshot or PDF work where browser fidelity matters more than the smallest image.
Best Value
- Used Book in Good Condition
Whichever mode you select, make it an explicit operational decision. Record the mode, browser version, container image and reason in the build configuration. Re-run a visual and functional smoke suite when Puppeteer or Chrome changes, because the old-mode flag is no longer a fallback you can restore.
Or skip the browser setup
If your goal is simply to obtain a clean website screenshot rather than drive a browser yourself, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response reports the result through X-Page-Verdict and X-Billed headers.
The one-call API example is documented at ScreenshotNeo’s 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
Equivalent Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Equivalent 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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element shots, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper sizes and page ranges, HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, selector/delay/network-idle waits, request and resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing migration.
An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. Every feature is available on every plan: 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
Final migration checklist
- Use
headless: trueor omit the option for unified Headless. - Remove every
--headless=oldreference. - Use
headless: 'shell'only for a documented compatibility or footprint reason. - Run visual, extension, download, PDF, authentication and timing checks.
- Compare headful and Headless runs when diagnosing a difference.
- Record Puppeteer, Chrome and mode versions in CI.
Frequently Asked Questions
Can I keep using --headless=new in a direct Chrome command?
Yes. Chrome 132 and later treat --headless=new as unified Headless, but plain --headless selects the same mode and is simpler.
Will changing the Headless mode require rewriting my page automation?
Usually the launch configuration is the only required code change. Re-test timing-sensitive flows, rendering, downloads, extensions and permissions because the browser implementation can expose assumptions that were hidden by the previous mode.
Recommended Free Tools
Quick Recap
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.

