← Blog

BLOG

Playwright ConnectOverCDP APK: What It Means and What to Use

Playwright connectOverCDP APK searches mix two different things. Here's what connectOverCDP actually does and how to connect to a remote browser.

September 23, 20268 min readRemote Browser

# Playwright ConnectOverCDP APK: What It Means and What to Use

If you searched for playwright connectovercdp apk, you are probably trying to connect Playwright to a browser that is not running on your machine — and you may have run into an Android APK somewhere in the results. Those are two unrelated things. connectOverCDP is a Playwright method for attaching to a Chromium instance over the Chrome DevTools Protocol. An APK is an Android package file. Playwright does not ship an APK, and connectOverCDP does not target Android apps.

What you likely want is a way to point Playwright at a remote Chromium endpoint and drive it from your code. That is exactly what browserType.connectOverCDP() does, and it is the same primitive that hosted browser runtimes expose to AI agents and automation pipelines. This guide explains what connectOverCDP actually does, why the APK association is a dead end, and how to wire it up against a remote browser in production.

What Playwright connectOverCDP actually does

browserType.connectOverCDP(endpointURL, options) connects to an existing Chromium-based browser over CDP and returns a Browser object. You do not launch a browser. You attach to one that is already running and exposing a DevTools endpoint — typically a WebSocket URL like ws://host:port/devtools/browser/<id> or an HTTP endpoint that Playwright resolves to one.

The key properties:

  • Chromium only. connectOverCDP works with Chromium, Chrome, Edge, and other Chromium-derived browsers. It is not a Firefox or WebKit path.
  • You get the existing context. Unlike launch(), you do not create a fresh browser context by default. You get browser.contexts() — the contexts already open on the remote instance. You can create new ones, but the default behavior is to attach to what is there.
  • CDP is the transport. Everything flows over the DevTools Protocol. That means the remote browser must have a CDP endpoint enabled and reachable from your network.

A minimal connection looks like this:

import { chromium, Browser, BrowserContext, Page } from 'playwright';

async function attachToRemote(): Promise<void> {
  const browser: Browser = await chromium.connectOverCDP(
    process.env.CDP_ENDPOINT!, // e.g. wss://<session-host>/cdp
    { timeout: 30_000 }
  );

  // connectOverCDP attaches to existing contexts by default.
  const contexts: BrowserContext[] = browser.contexts();
  const context: BrowserContext =
    contexts.length > 0 ? contexts[0] : await browser.newContext();

  const page: Page = context.pages()[0] ?? (await context.newPage());

  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
  console.log(await page.title());

  // Do NOT call browser.close() on a shared remote session unless you own it.
  await browser.close();
}

attachToRemote().catch((err) => {
  console.error('CDP attach failed:', err);
  process.exit(1);
});

Two things trip people up here. First, browser.contexts() may be empty if the remote instance has no open contexts — handle that case explicitly. Second, browser.close() on a CDP connection closes the connection, and depending on the remote runtime it may also tear down the underlying browser. If the session is shared or metered, check the runtime's semantics before calling it.

The APK association comes from a few places, none of which are Playwright:

  1. Android automation is a separate stack. If you want to drive a real Android device or emulator, you use ADB, Appium, or a cloud device farm. Playwright's connectOverCDP does not talk to Android's WebView debugging bridge in any supported way.
  2. Chrome on Android exposes a different debugging surface. Remote debugging for Chrome on Android goes through chrome://inspect and ADB port forwarding, not a Playwright CDP endpoint.
  3. Search engines blend the terms. "connectOverCDP" and "APK" co-occur in forum threads where someone tried to automate a mobile app and landed on the wrong tool.

If your actual goal is mobile web automation, the practical answer is to run Chromium in a hosted environment with a mobile viewport and user agent, not to chase an APK. If your goal is native Android app automation, Playwright is the wrong tool entirely.

What you actually need: a reachable CDP endpoint

The real prerequisite for connectOverCDP is a Chromium instance that exposes CDP and is reachable from wherever your code runs. You have three broad options.

ApproachSetup costIsolationScalingBest for
Local Chromium with --remote-debugging-portLowNone (shared machine)ManualDebugging, one-off scripts
Self-hosted Chromium fleet (Docker, VMs)HighPer-containerYou build itTeams with infra capacity
Hosted browser runtime with CDP endpointLowPer-sessionManagedAI agents, production automation

The local option is fine for development. You launch Chrome with a debugging port, then connect:

chrome --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile

Then point connectOverCDP at http://localhost:9222. This works, but it does not survive contact with production. You get one browser, one profile, no isolation between jobs, and no way to run more than a handful of concurrent sessions on a laptop.

Self-hosting is the middle path. You containerize Chromium, expose the CDP port, and manage lifecycle, proxies, and cleanup yourself. This is viable if you already run container orchestration and have someone who owns it. The failure modes are predictable: zombie browsers, port exhaustion, profile corruption, and no visibility into what a session is doing.

A hosted runtime collapses that into an endpoint. You request a session, get a CDP URL, and pass it to connectOverCDP. The runtime handles isolation, lifecycle, and cleanup. This is the model that most AI agent frameworks assume today, because agents need to spin up and tear down browser sessions far faster than a human can manage containers.

For a deeper look at how that runtime layer fits into agent architectures, see Remote browsers for AI agents.

Connecting Playwright to a hosted browser

The connection code is nearly identical to the local case. The difference is where the endpoint comes from and what guarantees surround it.

import { chromium } from 'playwright';

const cdpUrl = process.env.REMOTE_BROWSER_CDP_URL!;

const browser = await chromium.connectOverCDP(cdpUrl, {
  timeout: 30_000,
});

const context = browser.contexts()[0] ?? (await browser.newContext({
  viewport: { width: 1440, height: 900 },
}));

const page = context.pages()[0] ?? (await context.newPage());
await page.goto('https://example.com');

What matters in production is not the connection call — that is three lines. What matters is everything around it:

  • Session lifecycle. Who creates the session, who ends it, and what happens if your process crashes mid-task. A hosted runtime should reclaim orphaned sessions automatically.
  • Profile persistence. If your agent logs in once and needs that state next run, you need persistent profiles. connectOverCDP alone does not give you that; the runtime does.
  • Network configuration. Proxies, geolocation, and browser settings are configured at the session level, not in your Playwright code. See Remote Browser online for how session configuration works.
  • Observability. When an agent fails at step 14, you need to see what the page looked like. A live viewer or session recording is the difference between a five-minute fix and a two-hour mystery.

Production criteria for a CDP endpoint

Not every CDP endpoint is suitable for agent workloads. Here is what to evaluate.

Isolation. Each session should have its own browser process and profile. Shared browsers leak state between jobs — cookies, local storage, and sometimes auth tokens. If two agents can see each other's tabs, that is a bug, not a feature.

Endpoint stability. CDP WebSocket URLs should remain valid for the life of the session. If the endpoint rotates or requires reconnection mid-task, your agent needs reconnection logic, which is easy to get wrong.

Concurrency controls. You need to know your limits before you hit them. Whether that is a per-account cap or a rate limit, it should be documented and enforceable in code. Check pricing for current session and concurrency details rather than assuming.

Protocol fidelity. Some hosted browsers expose a subset of CDP. If your automation relies on specific domains like Network, Fetch, or Page, verify they are available. Playwright's higher-level API covers most needs, but raw CDP calls through context.newCDPSession(page) may not work everywhere.

Latency. CDP is chatty. Every page.click() can be several round trips. If your code runs in us-east-1 and the browser runs in eu-west-1, you will feel it. Co-locate your worker and the browser region.

Where connectOverCDP fits in agent stacks

For AI browser agents, connectOverCDP is the transport, not the architecture. The agent framework — whether that is browser-use, a custom loop, or a hosted agent runtime — decides what to do on the page. Playwright's CDP connection is how it gets there.

This matters because it decouples two concerns that used to be tangled: what the agent does and where the browser runs. You can swap the agent model, change the task, or scale the workload without touching the browser infrastructure. The CDP endpoint stays the same.

It also means you can use the same endpoint from multiple tools. Playwright, Puppeteer, and raw CDP clients can all attach to the same session type. If you are evaluating browser runtimes for an agent project, that flexibility is worth weighing. For a comparison of control models, see Remote control browser.

Common failure modes

Connection refused or timeout. The endpoint is wrong, the session expired, or a firewall is blocking the WebSocket. Verify the URL and that your egress allows wss://.

`browser.contexts()` is empty. The remote instance has no open contexts. Create one explicitly instead of assuming.

Target closed errors mid-task. The session was reclaimed, the browser crashed, or something called close(). Add retry logic and check session health before long operations.

CDP domain not found. The runtime exposes a restricted CDP surface. Check which domains are available before relying on raw protocol calls.

Slow operations. Usually a region mismatch or an overloaded session. Measure round-trip latency to the endpoint before blaming your code.

Summary

playwright connectovercdp apk is a search that conflates a Playwright method with an Android package format. They are unrelated. connectOverCDP attaches Playwright to an existing Chromium instance over the DevTools Protocol — that is all it does, and it does it well.

If you need to drive a browser from code or an AI agent, the question is not whether to use connectOverCDP. It is where the browser runs and what guarantees the runtime provides. A hosted browser runtime gives you a CDP endpoint, session isolation, persistent profiles, and lifecycle management without you building any of it. Start with the documentation to see how sessions and endpoints are exposed, and check pricing for current usage details.

For the official protocol reference, see the Chrome DevTools Protocol documentation and Playwright's `browserType.connectOverCDP` API page.