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

To connect Puppeteer to a browser that is already running, retrieve its Chrome DevTools Protocol (CDP) WebSocket URL and pass it to puppeteer.connect(). Puppeteer’s documented discovery endpoint is http://HOST:PORT/json/version; use the response’s webSocketDebuggerUrl value.

Find the browser’s WebSocket endpoint

The browser must already be running and expose a debugging endpoint that your Node.js process can reach. Request http://HOST:PORT/json/version, substituting the host and port configured for that browser. In the returned JSON, copy the value of webSocketDebuggerUrl. Puppeteer documents the WebSocket endpoint shape as ws://HOST:PORT/devtools/browser/<id>. The host, port, and browser ID depend on the running instance; do not assume that another browser or session’s endpoint will work.

For example, if the endpoint response contains a webSocketDebuggerUrl beginning with ws://127.0.0.1:9222/devtools/browser/, pass that complete value—not just the host and port—to Puppeteer. See the Puppeteer browser management guide and the Browser.wsEndpoint() reference.

Connect from Node.js

Install Puppeteer in the Node.js project that will control the browser. Then use the endpoint from /json/version:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
const puppeteer = require('puppeteer');

async function main() {
  const browser = await puppeteer.connect({
    browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser/REPLACE_WITH_BROWSER_ID',
  });

  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');
    console.log(await page.title());
  } finally {
    browser.disconnect();
  }
}

main().catch(console.error);

Replace the sample endpoint with the complete webSocketDebuggerUrl returned by your browser. puppeteer.connect() resolves to a Browser object; use browser.pages() to inspect available pages or browser.newPage() to create one. The API’s explicit connection example uses browserWSEndpoint; see Puppeteer’s connect API.

Choose how Puppeteer should detach

Decide whether your script owns the browser process or is only borrowing the connection. This choice matters especially for persistent browsers and shared automation environments.

  • browser.disconnect() detaches Puppeteer while leaving the browser process and its pages running. Use it when another process or later task should keep using that browser.
  • browser.close() closes the browser. Use it only when your code is meant to end the browser session.

Do not use close() as routine cleanup when you need the existing browser to remain available.

Use contexts when tasks need separate storage

Pages in the same browser context share that context’s browser state. To keep separate tasks from sharing cookies and local storage, create separate BrowserContexts. Puppeteer’s browser management guide documents that cookies and local storage are not shared between contexts. This is storage isolation within the connected browser, not a separate browser process.

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.

Protocol and runtime considerations

  • Default protocol: Puppeteer’s ConnectOptions documentation says the protocol is determined at runtime and defaults to CDP when connecting to a browser. WebDriver BiDi is an explicit case, configured with protocol: "webDriverBiDi" where supported.
  • Experimental channel option: channel is marked experimental for connect(). The reference describes it as looking for an open WebSocket in the channel’s well-known default user data directory, and says it works only for Chrome in Node.js. Treat it as a special case, not a replacement for the endpoint workflow.
  • Browser runtime: A browser-compatible Puppeteer build can connect through WebSockets to an existing browser from a browser page runtime. Launching or downloading a browser is not supported there because those operations rely on Node.js APIs. The official guide uses the browser-specific puppeteer-core entry point.
  • Version and compatibility: The official API reference displayed Puppeteer 25.12.0 when checked on October 3, 2026. Documentation establishes the API and endpoint format, not compatibility with every Chrome, Chromium, or remote-browser deployment. Confirm that the browser exposes the expected protocol and that its endpoint is reachable from the process running Puppeteer.

browserURL is also listed in ConnectOptions as a connection option. The documentation cited here does not establish enough detail to give a specific URL format or decision rule for it, so the WebSocket endpoint is the clearest general recipe.

Troubleshoot connection failures

  • Cannot reach /json/version: Check that the browser is running, that its debugging endpoint is enabled, and that the host and port are correct and reachable from the Puppeteer process. The reviewed Puppeteer documentation explains endpoint discovery but does not provide one launch command that applies to every operating system or managed browser service.
  • Connection fails with an endpoint error: Copy the complete webSocketDebuggerUrl from the current browser instance’s JSON response. A stale URL, a URL from another session, or a value containing only the HTTP host and port is not the documented WebSocket URL.
  • The script closes a browser others still need: Replace browser.close() with browser.disconnect() when Puppeteer should detach without terminating the browser.
  • Cookies or local storage appear missing: Check which BrowserContext the page belongs to. Separate contexts intentionally do not share cookies or local storage.
  • A browser-page script cannot launch a browser: That runtime can connect to an existing browser, but launching or downloading one requires Node.js APIs and is not supported there.

Or skip the browser setup

If your goal is a website screenshot rather than controlling an existing browser, ScreenshotNeo returns an image or PDF with one GET request. Its screenshot API is ScreenshotNeo; the API documentation covers the request options.

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 and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month—no card required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Frequently Asked Questions

Does Puppeteer launch a new browser when I call connect()?

No. connect() attaches to an already running browser. Launching a browser is a separate operation.

Can I keep the connected browser open after my script exits?

Yes. Detach with browser.disconnect() rather than closing the browser.

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.