BLOG
Remote Chromium API Download: What You Actually Install
A remote Chromium API download is usually a client SDK, not a browser binary. Learn what to install, what to skip, and how to connect over CDP.
# Remote Chromium API Download: What You Actually Install
If you searched for a "remote chromium api download," you probably expect a file. In practice, a remote Chromium API is almost never something you download as a browser binary. The Chromium instance runs on a provider's infrastructure, and what you install locally is a thin client: an SDK, a CLI, or just an existing automation library like Playwright or Puppeteer pointed at a WebSocket endpoint. Understanding that split early saves you from downloading a large browser binary you will never use.
This guide explains what a remote Chromium API download actually consists of, how the connection works over the Chrome DevTools Protocol (CDP), and what to evaluate before you commit to a runtime. If you want the broader architecture first, see Remote browsers for AI agents.
What "remote Chromium API download" really means
The phrase bundles two different things:
- The browser. A real Chromium build running in a data center, isolated per session, reachable over a network endpoint.
- The API client. The code on your machine that talks to that browser — usually a small npm package, a Python wheel, or nothing at all if you already use Playwright or Puppeteer.
When people say "download the remote Chromium API," they usually mean one of these:
- Installing a provider's SDK (
npm install @provider/sdk). - Installing a CLI that wraps session creation and CDP connection.
- Installing Playwright or Puppeteer, which already speak CDP and need no provider-specific package.
- Downloading a Chromium binary locally — which is the one thing you *don't* need for a remote setup.
The last point matters. A local Chromium download is roughly 150–300 MB depending on platform, plus a headless shell variant. If your browser lives in the cloud, that download is dead weight in your container image, your CI cache, and your deploy pipeline.
The endpoint is the product, not the binary
A hosted Chromium session exposes a CDP WebSocket URL. That URL is the entire contract. Anything that can open a WebSocket and speak CDP can drive the browser: Playwright, Puppeteer, Selenium via a CDP bridge, raw chrome-remote-interface, or a custom agent loop.
So the real "download" question becomes: *what client do I need to connect to a wss:// endpoint?* For most teams, the answer is a library you already have.
What you actually install
Here is a practical breakdown of what ends up in your dependency tree for a remote Chromium setup.
| Component | Typical size | Needed for remote? | Notes |
|---|---|---|---|
| Playwright or Puppeteer package | ~10–40 MB | Yes (one of them) | Speaks CDP natively |
| Provider SDK | ~1–5 MB | Optional | Convenience wrapper for session lifecycle |
| Provider CLI | ~5–20 MB | Optional | Useful for scripts and debugging |
| Local Chromium binary | 150–300 MB | No | Only for local runs or fallback |
| Headless shell | ~80–120 MB | No | Skip if browser is remote |
| Browser drivers (Selenium) | ~10 MB | Only for Selenium | Not needed for CDP-native clients |
If you are on Playwright, you can skip npx playwright install chromium entirely for remote-only workloads. That single change often cuts CI image size and cold-start time noticeably. For the local-vs-remote trade-off in detail, see Playwright browsers download and Remote browser online.
When you do need a local binary
There are legitimate cases:
- Local development and debugging. Running a real browser on your laptop is faster to iterate against than a remote session.
- Fallback paths. Some teams keep a local Chromium for offline tests or when the remote provider is unreachable.
- Recording and fixture generation. Capturing traces locally before replaying remotely.
For everything else — production agents, CI test suites, scheduled automation — the remote endpoint replaces the binary.
How the connection works: CDP over WebSocket
CDP is a JSON-based protocol over WebSocket. You connect to a browser-level endpoint, then attach to targets (pages, iframes, workers) and send commands like Page.navigate, Runtime.evaluate, or Network.enable. The Chrome DevTools Protocol documentation is the authoritative reference for the command surface.
A remote Chromium API is essentially a managed CDP endpoint plus session lifecycle around it: create a session, get a wss:// URL, connect, drive, disconnect, and let the provider tear down the browser.
A minimal Playwright connection in TypeScript
The following example assumes your provider returns a CDP WebSocket URL when you create a session. Replace the session-creation call with your provider's SDK or HTTP endpoint.
import { chromium, Browser, Page } from "playwright";
interface SessionInfo {
cdpUrl: string; // wss://... from your provider
sessionId: string;
}
async function createSession(): Promise<SessionInfo> {
// Replace with your provider's session-creation call.
const res = await fetch("https://api.example-provider.dev/v1/sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.BROWSER_API_KEY}`,
},
body: JSON.stringify({ region: "us-east", profile: "default" }),
});
if (!res.ok) throw new Error(`session create failed: ${res.status}`);
return (await res.json()) as SessionInfo;
}
async function run(): Promise<void> {
const session = await createSession();
let browser: Browser | undefined;
try {
browser = await chromium.connectOverCDP(session.cdpUrl);
const context = browser.contexts()[0] ?? (await browser.newContext());
const page: Page = context.pages()[0] ?? (await context.newPage());
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
const title = await page.title();
console.log("title:", title);
// CDP session for lower-level control when Playwright's API is not enough.
const cdp = await context.newCDPSession(page);
await cdp.send("Network.enable");
cdp.on("Network.responseReceived", (event) => {
if (event.response.status >= 400) {
console.warn("bad response:", event.response.url, event.response.status);
}
});
await page.click("a");
await page.waitForLoadState("networkidle");
} finally {
// Disconnect the client; the provider decides when to stop the browser.
await browser?.close();
}
}
run().catch((err) => {
console.error(err);
process.exit(1);
});Two details worth noting:
connectOverCDPattaches to an existing browser. It does not launch one, so no local Chromium is required.browser.close()on a CDP connection disconnects the client. Whether the remote session stops depends on the provider's lifecycle model — check the docs for your runtime.
If you are wiring an agent rather than a test, the same pattern applies; the difference is who decides the next action. For that angle, see Remote control browser.
What to evaluate in a remote Chromium API
Not all hosted Chromium endpoints are equivalent. The differences that matter in production are rarely about the download size of the client.
Session lifecycle and isolation
Ask:
- Is each session a fresh browser process, or a shared browser with isolated contexts?
- What happens to a session when the client disconnects unexpectedly?
- Are there hard timeouts, and can they be extended?
- Can you persist a profile across sessions, and how is that storage scoped?
Session isolation is the security boundary. If two tenants can share a browser process, you are trusting the provider's context isolation more than you would trust a process boundary.
CDP fidelity
Some providers proxy CDP with a restricted command allowlist. That can break tools that rely on less common domains — Target.setAutoAttach, Fetch.enable, Emulation.setDeviceMetricsOverride, and so on. If your automation depends on a specific CDP domain, verify it works before you build on it.
Profiles and state
Persistent profiles let an agent keep cookies, local storage, and logged-in state across sessions. This is the difference between an agent that re-authenticates every run and one that behaves like a returning user. Check how profiles are created, named, and deleted, and whether they are portable between regions.
Network controls
Proxy configuration, geo selection, and configurable browser settings are common. Be precise about what you need: a residential proxy pool is a different product from a datacenter egress IP, and "stealth" means different things at different providers. Prefer providers that document exactly which settings are configurable rather than making broad claims.
Observability
A live viewer, session recordings, and CDP-level logs are what you use when an agent fails at step 14 of a 20-step task. Without them, debugging a remote session is guesswork. Confirm whether the viewer is real-time, whether recordings are retained, and whether you can attach your own CDP client alongside the provider's tooling.
Pricing model
Browser-hour metering is the norm, but the details differ: what counts as a billable hour, whether idle time is billed, and whether concurrency is capped by plan. Do not assume a headline rate applies to your workload. Check pricing for current details and model your expected session count and duration before committing.
Common mistakes with remote Chromium downloads
A few patterns show up repeatedly when teams move from local to remote:
- Installing Chromium "just in case." If the container never launches a local browser, the binary only slows builds. Remove it and let the remote endpoint be the only browser.
- Pinning Playwright and Chromium versions independently. With
connectOverCDP, the remote browser version is the provider's, not yours. Test against the version you will actually get. - Assuming `browser.close()` stops billing. Disconnecting a client and terminating a session are different operations. Read the lifecycle docs.
- Ignoring reconnect behavior. Long-running agents lose WebSocket connections. Plan for reconnection or session resumption rather than treating a dropped socket as a fatal error.
- Skipping the viewer during development. The live viewer is the fastest way to see what an agent is actually doing. Use it before you write elaborate logging.
When a local Chromium download still makes sense
Remote is not universally better. Keep a local browser when:
- You are developing selectors and flows and want sub-second iteration.
- You need to test browser-version-specific behavior that the provider does not expose.
- You have compliance constraints that forbid sending page content to a third party.
- Your workload is small enough that managing a local browser is cheaper than a hosted session.
The decision is about where the browser runs, not about which API you use. Playwright and Puppeteer code is largely portable between the two; the connection line changes, the automation logic usually does not.
A practical migration path
If you are moving an existing local setup to a remote Chromium API, the sequence that tends to work:
- Keep local for development. Do not rip out the local browser on day one.
- Abstract session creation. Put browser acquisition behind a function that returns a connected
Browser. Swap local launch forconnectOverCDPin one place. - Remove the Chromium install from CI. Once remote tests pass consistently, drop
playwright installfrom the pipeline. - Add profiles for stateful flows. Move login-dependent tests and agents onto persistent profiles.
- Instrument failures. Wire the live viewer and recordings into your debugging workflow before scaling concurrency.
- Model cost. Track session count and duration for a week, then compare against pricing.
This order keeps the blast radius small. Each step is reversible, and you learn where the remote runtime differs from local before you depend on it.
Bottom line
A remote Chromium API download is mostly a client-side concern: a Playwright or Puppeteer package, optionally a provider SDK, and a CDP WebSocket URL. The browser itself stays in the cloud, which is the point — no 300 MB binary in your image, no version drift between local and production, and a session lifecycle you can meter and observe.
The things that actually determine whether a remote Chromium API works for you are CDP fidelity, session isolation, profile handling, network controls, observability, and pricing transparency. Evaluate those before you evaluate the download. For a deeper look at the runtime model, read Remote web browser and the documentation.