BLOG
Playwright connect_over_cdp Chromium Only Docs: A Practical Guide
Playwright connect_over_cdp chromium only docs: learn how to connect to remote Chromium instances via CDP, and why Firefox support is limited.
# Playwright connect_over_cdp Chromium Only Docs: A Practical Guide
If you've searched for Playwright connect_over_cdp chromium only docs, you've likely hit a wall: the official Playwright documentation states that connectOverCDP works with Chromium-based browsers, but the details on why Firefox is excluded, how to handle WebSocket endpoints, and what production considerations matter are scattered. This guide consolidates the official docs, explains the technical constraints, and shows you how to use connectOverCDP to attach Playwright to a remote Chromium instance—whether it's running locally, in a Docker container, or as part of a hosted browser service.
What Is connectOverCDP and Why Does It Matter?
browserType.connectOverCDP() is a Playwright API that allows you to attach to an existing Chromium browser instance via the Chrome DevTools Protocol (CDP). Unlike browserType.launch(), which spawns a new browser process, connectOverCDP connects to a browser that is already running. This is essential for:
- Debugging live sessions: Attach to a browser that a user or AI agent is actively using.
- Scaling browser workloads: Launch browsers in separate containers or cloud VMs and connect to them from your application server.
- Reusing persistent profiles: Connect to a browser with a specific profile, cookies, or local storage without restarting.
The official Playwright docs are clear: connectOverCDP is only supported in Chromium-based browsers. Firefox and WebKit do not support this method. This is not a Playwright limitation per se—it's a protocol limitation. Firefox uses the Remote Protocol (a different debugging protocol), and WebKit has its own Web Inspector protocol. Neither is compatible with CDP.
The Core Problem: Why "Chromium Only"?
The phrase "chromium only" in the docs isn't a suggestion; it's a hard technical constraint. Here's why:
- CDP is Chrome's native protocol: The Chrome DevTools Protocol is a set of JSON-RPC methods and events that allow external tools to inspect and control Chromium. Firefox and WebKit have their own protocols.
- Playwright's implementation: Playwright's
connectOverCDPmethod speaks CDP directly. It doesn't translate between protocols. If you try to use it with Firefox, you'll get an error like"connectOverCDP" is not supported in Firefox. - Feature parity: Even if you could connect to Firefox via a different protocol, Playwright's high-level API (e.g.,
page.click(),page.fill()) relies on CDP-specific commands for certain operations. These commands are not available in Firefox's protocol.
What About playwright.connect()?
Playwright also offers playwright.connect(), which connects to a browser launched via playwright-server or a browser launched with --remote-debugging-pipe. This method does support Firefox and WebKit because it uses Playwright's own wire protocol, not CDP. However, the browser must be launched by Playwright itself, not an external process. If you need to attach to an already-running browser, connectOverCDP is your only option—and it's Chromium-only.
How to Use connectOverCDP with Chromium
Let's walk through a concrete example. Assume you have a Chromium instance running with remote debugging enabled:
chromium --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-profileNow, from your Node.js application, you can connect to it:
import { chromium } from 'playwright';
async function main() {
// Connect to the existing Chromium instance via CDP
const browser = await chromium.connectOverCDP('http://localhost:9222');
// Get the default context (the one associated with the browser's main profile)
const defaultContext = browser.contexts()[0];
const page = defaultContext.pages()[0];
// Or create a new page in the existing context
const newPage = await defaultContext.newPage();
await newPage.goto('https://example.com');
console.log(await newPage.title());
// Don't close the browser—you're connected to an external process
await browser.close();
}
main();Key takeaways from this example:
browser.contexts()returns the existing browser contexts. If you launched Chromium with a--user-data-dir, you'll get a default context.browser.close()in this mode disconnects from the browser but does not terminate the browser process. This is a common source of confusion.- You can connect to a remote WebSocket endpoint (e.g.,
ws://remote-host:9222/devtools/browser/...) instead of an HTTP URL.
Connecting to a Remote WebSocket Endpoint
If your Chromium instance is behind a reverse proxy or running in a cloud container, you'll likely connect via WebSocket:
const browser = await chromium.connectOverCDP('ws://remote-host:9222/devtools/browser/7a2c3d4e-...');The WebSocket URL is typically printed to the browser's stderr when you launch it with --remote-debugging-port=0. For a fixed port like 9222, you can fetch the browser WebSocket URL from http://localhost:9222/json/version.
Production Considerations for connectOverCDP
Using connectOverCDP in production is different from using it in a local script. Here are the trade-offs and criteria you need to evaluate.
1. Session Persistence Across Workers
A common question is: *"How do I keep browser sessions alive across multiple cloud workers?"* With connectOverCDP, the browser is a separate process. Your application server can connect, perform actions, disconnect, and reconnect later. The browser state (cookies, localStorage, etc.) persists as long as the browser process is alive.
The catch: If your worker crashes or the network drops, the connection is lost. The browser keeps running, but you need a reconnection strategy. Playwright does not auto-reconnect. You'll need to wrap your connection logic in a retry loop.
2. Scaling Browser Workloads
connectOverCDP is ideal for scaling because you can decouple the browser lifecycle from your application lifecycle. Instead of launching a browser per test or per agent task (which is slow and resource-intensive), you can maintain a pool of long-running Chromium instances and connect to them on demand.
However, this introduces orchestration complexity. You need to manage:
- Browser pool sizing: How many Chromium instances do you need? Each instance consumes significant RAM (typically 300-600 MB).
- Load balancing: Which browser should a new task connect to?
- Health checks: How do you detect and restart hung browsers?
This is where a hosted browser service like Remote Browser becomes practical. It abstracts away the orchestration layer, giving you a simple API to connect to a managed Chromium session.
3. Security and Network Exposure
Exposing a CDP endpoint (port 9222) to the network is a security risk. CDP allows full control of the browser, including reading cookies, accessing local files, and executing arbitrary JavaScript. If you expose it without authentication, anyone on your network can hijack the browser.
Production best practices:
- Bind CDP to
localhostand use an SSH tunnel or a reverse proxy with authentication. - Use a firewall to restrict access to the CDP port.
- Consider using
--remote-debugging-pipeinstead of a port, which is more secure but harder to use over a network.
4. Firefox and WebKit: What Are Your Options?
If you need Firefox or WebKit, connectOverCDP won't work. Your options are:
- Use `playwright.connect()`: This requires the browser to be launched by Playwright's server component. You can run
npx playwright-serverand connect to it, but this doesn't let you attach to an existing browser with a user profile. - Use Selenium Grid: Selenium supports Firefox and WebKit via its own protocol, but it's a heavier setup and doesn't expose the full Playwright API.
- Use a hosted service: Some browser services offer Firefox support, but they typically use their own proprietary APIs rather than CDP.
For most production workloads, Chromium is the pragmatic choice. It's the most widely tested browser for automation, and its CDP support is mature.
Comparison: connectOverCDP vs. launch() vs. Hosted Browsers
| Feature | launch() | connectOverCDP() | Hosted Browser (e.g., Remote Browser) |
|---|---|---|---|
| Browser lifecycle | Managed by Playwright | External process | Managed by service |
| Firefox/WebKit support | Yes | No (Chromium only) | Varies; often Chromium-only |
| Attach to existing session | No | Yes | Yes |
| Persistent profile | Manual (user-data-dir) | Yes (if browser has profile) | Yes (managed profiles) |
| Scaling | Per-process, resource-heavy | Pool of browsers, complex orchestration | API-based, auto-scaling |
| Network security | Local only | Must secure CDP endpoint | Managed by service |
| Debugging | Playwright Inspector | CDP tools (Chrome DevTools) | Live viewer, CDP access |
| Cost | Infrastructure only | Infrastructure + orchestration | Per-browser-hour pricing |
How to Give Your AI Agent Browser Access in Production
If you're building an AI agent that needs to browse the web, connectOverCDP is a powerful primitive, but it's not a complete solution. Here's what you need to consider:
- Session isolation: Each agent task should ideally get a fresh browser profile to avoid cross-task contamination. With
connectOverCDP, you'd need to manage multiple browser instances with different--user-data-dirpaths. - Proxy and IP management: If your agent needs to access geo-restricted content or avoid rate limiting, you'll need to configure proxies. CDP allows you to set proxies via
--proxy-server, but managing this per-session is tedious. - Stealth and anti-detection: Some sites block headless browsers. While CDP lets you run headed browsers, you may need additional configuration to avoid detection. This is an area where hosted services often provide "configurable browser settings" that go beyond vanilla Chromium.
For a production AI agent, the question isn't just *how to connect* but *how to manage the full browser lifecycle*. A hosted browser API handles session persistence, proxy configuration, and live debugging out of the box, so you can focus on your agent's logic rather than browser infrastructure.
Why Remote Browser Uses Chromium and CDP
At Remote Browser, we've standardized on Chromium and CDP for a simple reason: it's the most reliable, well-documented path for browser automation. Our hosted Chromium sessions are fully compatible with Playwright's connectOverCDP, so you can use the code above with a simple URL swap:
const browser = await chromium.connectOverCDP('wss://remote-browser.dev/...');This gives you:
- Persistent profiles: Your browser session survives disconnects.
- Live debugging: Watch your agent or test in real-time via a live viewer.
- Scalable infrastructure: No need to manage browser pools or worry about CDP port security.
We handle the orchestration, security, and scaling so you can use the standard Playwright API you already know.
Conclusion: connectOverCDP Is Powerful, But Chromium-Only
To summarize the Playwright connect_over_cdp chromium only docs:
connectOverCDPis a Chromium-only feature. It does not work with Firefox or WebKit.- It's the right tool when you need to attach to an existing browser, not launch a new one.
- In production, you must handle session persistence, reconnection, and CDP security yourself.
- For complex workloads—especially AI agents that need persistent, secure, and scalable browser access—a hosted Chromium runtime is often the more practical choice.
If you're ready to move beyond local scripts and need a production-grade browser runtime, explore our documentation to see how Remote Browser integrates with Playwright via CDP. You can also check our pricing page for current plans, or read about how to keep browser sessions alive across cloud workers and why hosted Chromium beats local setup.
For the authoritative source on Playwright's CDP support, refer to the official Playwright documentation on browserType.connectOverCDP.