Puppeteer connects to a browser through a transport, then sends commands using a browser protocol such as Chrome DevTools Protocol (CDP) or WebDriver BiDi. For an existing browser, connect with its WebSocket endpoint; for a launched Chrome process, you can request pipe communication instead. These are connection choices, not protocol names.
How Puppeteer connects to a browser
Puppeteer can launch a browser or attach to one that is already running. When attaching, obtain the browser’s WebSocket endpoint and pass it to puppeteer.connect(). The connection options also allow a browser URL or a custom transport. See the ConnectOptions API reference.
As an Amazon Associate I earn from qualifying purchases.
import puppeteer from 'puppeteer';
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://HOST:PORT/devtools/browser/ID',
});
try {
const pages = await browser.pages();
console.log(`Connected; ${pages.length} page(s) are open.`);
} finally {
await browser.disconnect();
}
Replace the endpoint with the actual URL for your browser. The sample disconnects the Puppeteer client when done, leaving the browser process running.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsFinding the WebSocket endpoint
browser.wsEndpoint() returns the endpoint for a browser launched or managed through Puppeteer. Its conventional shape is ws://HOST:PORT/devtools/browser/<id>. For an already-running browser, the browser’s /json/version response exposes the field webSocketDebuggerUrl. The Browser.wsEndpoint() reference documents both the endpoint format and lookup route.
#1 Best Overall
const endpoint = browser.wsEndpoint();
console.log(endpoint);
If you are connecting remotely, use the endpoint supplied by the browser host or service; do not assume the example host, port, or ID is valid for your environment.
Transport and protocol are different layers
The transport carries messages between the Puppeteer client and browser process. CDP or WebDriver BiDi defines the browser protocol spoken over that connection. Treating “WebSocket” and “CDP” as interchangeable confuses the delivery path with the command language.
Puppeteer’s documented protocol default depends on how the browser is used: launching Chrome selects CDP, launching Firefox selects WebDriver BiDi, and connecting to a browser defaults to CDP. The default for a connection therefore should not be generalized to every launch or browser. Details are in the ConnectOptions API reference.
WebSocket versus pipe
| Choice | When it applies | Important constraint |
|---|---|---|
| WebSocket | Common option for attaching to an existing browser using its endpoint. | Requires an endpoint reachable by the Puppeteer client. |
| Pipe | Option for communication with a launched Chrome browser. | LaunchOptions.pipe is Chrome-only and defaults to false; it is not a replacement endpoint for attaching to an independently running browser. |
Set pipe: true in launch options to request pipe communication instead of WebSocket for Chrome. Puppeteer documents certain Progressive Web App operations—install, launch, and uninstall—as pipe-only. That is a concrete reason to choose pipe when those operations are needed; the documentation does not establish that pipe is generally faster or more reliable. See LaunchOptions and the Browser API.
Rank #3
const browser = await puppeteer.launch({
pipe: true,
});
What a custom ConnectionTransport must implement
The public ConnectionTransport contract is deliberately small. A custom transport must provide send(message) and close(), and may expose onmessage and onclose callbacks. Pass an implementation through the transport connection option. See ConnectionTransport and ConnectOptions.
send(message): accepts a message for transmission.close(): closes the transport.onmessage(optional): callback for incoming messages.onclose(optional): callback for closure.
This interface describes the abstraction’s public surface; it does not, by itself, specify wire framing, reconnection behavior, message ordering, or multiplexing guarantees. A custom implementation should follow the expectations of the browser protocol and Puppeteer version it is integrating with rather than assuming those behaviors from the interface alone.
Disconnecting is not the same as closing
Use browser.disconnect() to detach Puppeteer while leaving the remote browser and its pages running. Use browser.close() when Puppeteer should close the browser. This distinction matters when a browser is shared or managed separately from the script. The official browser management guide demonstrates connecting to an existing browser and disconnecting afterward.
Free tools Windows power users keep installed
One-click scans. No signup required.
Browser-side Puppeteer has a launch limitation
Puppeteer can run in a browser environment and connect to a separate browser over WebSocket. It cannot launch or download a browser in that environment because those operations depend on Node.js APIs. If Puppeteer runs in the browser, arrange for the browser process separately and connect to it. See the browser management guide.
Best Value
- Used Book in Good Condition
Common connection problems
- Endpoint unavailable or malformed: confirm you copied the complete
webSocketDebuggerUrlor the endpoint returned bybrowser.wsEndpoint(), and that the client can reach its host and port. - Trying to attach with pipe: the documented pipe option is for launching Chrome, not a WebSocket endpoint for an already-running browser. Use
browserWSEndpointorbrowserURLto attach. - Browser closes unexpectedly: check whether the code calls
browser.close(). Usedisconnect()if the intent is to detach without stopping the browser. - Pipe-only PWA operation fails: confirm the browser was launched with
pipe: true; the documented PWA install, launch, and uninstall operations require pipe. - Launch or download fails in browser-side Puppeteer: these operations require Node.js APIs. Launch or provide the browser elsewhere, then connect via WebSocket.
Or skip the browser setup
If your task is simply to capture a website screenshot, ScreenshotNeo provides a one-request screenshot API, rather than requiring you to launch and connect a browser yourself. Its endpoint can return PNG, JPEG, WebP, or PDF; see the ScreenshotNeo documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners before capture and removes known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, and failed loads are not billed. Its MCP server gives AI agents screenshot tools. The free plan includes 1,000 screenshots a 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.
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 →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.




