BLOG
Dev Browser: A Practical Runtime for AI Agents and Automation
A dev browser is hosted Chromium you drive over CDP. Learn how it works, when to use one, and how to wire Playwright, Puppeteer, or an agent to it.

A dev browser is a real Chromium instance running somewhere other than your laptop, exposed over a network protocol so your code or your agent can drive it. You get a WebSocket endpoint, connect over the Chrome DevTools Protocol (CDP), and run the same Playwright, Puppeteer, or Selenium calls you already know. The difference is that the browser lives on managed infrastructure with its own lifecycle, isolation, and viewer.
That definition matters because "dev browser" gets used loosely. Sometimes it means a browser embedded in an IDE. Sometimes it means a headless Chrome you shell into. For production work, the useful meaning is narrower: a hosted runtime you connect to, not a binary you install. This guide covers what a dev browser actually is, the trade-offs against local Chrome, the criteria that separate a toy from infrastructure, and how to wire one up with Playwright over CDP.
What a dev browser actually is
Strip away the marketing and a dev browser has four parts:
- A real browser process. Not a DOM emulator, not a headless shim. Chromium with a rendering engine, network stack, and JavaScript runtime.
- A control surface. CDP over WebSocket is the standard. It exposes pages, targets, network events, and input injection.
- A session lifecycle. Create, connect, use, stop. Sessions are isolated from each other and from your machine.
- An access layer. Authentication, a viewer for live debugging, and usage metering.
When you connect Playwright to a dev browser, you are not running a browser inside your Node process. You are sending protocol messages to a remote Chromium and receiving events back. That distinction drives almost every trade-off that follows.
The practical payoff is that the browser stops being a dependency of your application host. Your worker can be a small container, a serverless function, or a laptop on hotel Wi-Fi. The browser is elsewhere, and it stays alive across your process restarts if the session is configured to persist.
Why "just run Chrome locally" stops working
Local Chrome is fine until it isn't. The failure modes are predictable:
- Environment drift. Your laptop has Chrome 131, CI has 128, and the site you are automating behaves differently on each. Version pinning helps, but you now own the update treadmill.
- Resource contention. Ten parallel headless browsers will saturate a developer machine. Fifty will not fit at all.
- State leakage. Cookies, localStorage, and cached credentials bleed between test runs unless you isolate profiles carefully.
- No shared visibility. When an agent fails at step 14, nobody can watch it happen. You get a stack trace and a screenshot, if you are lucky.
- Network identity. Your CI runner's IP is a datacenter IP. Some sites treat that differently from a residential one.
A dev browser addresses these by moving the browser out of the blast radius of your application. You get consistent Chromium versions, isolated sessions, a live viewer, and configurable network settings. You also get a bill, which is the honest trade-off.
Dev browser vs local Chrome vs browser extension
There are three common ways people try to give an agent or a script a browser. They solve different problems.
| Approach | Control surface | Isolation | Scales past one machine | Live debugging | Best fit |
|---|---|---|---|---|---|
| Local Chrome + Playwright | In-process CDP | Weak (shared profile) | No | Manual | Solo development, quick scripts |
| Browser automation extension | Extension APIs, limited CDP | Per-tab, tied to your session | No | You are the viewer | Human-in-the-loop assist, not unattended agents |
| Hosted dev browser | CDP over WebSocket | Per-session | Yes | Built-in viewer | Agents, CI, scraping, multi-tenant automation |
The extension route deserves a note because it comes up often. A browser automation extension runs inside a browser you are already using, which is convenient for a human driving an agent. It is a poor fit for unattended work: the browser closes when you close your laptop, the extension's permissions are scoped to your session, and you cannot run twenty of them in parallel. If you need an agent to operate while you sleep, you need a runtime, not an extension.
For a deeper treatment of the runtime layer, see remote browsers for AI agents.
What to evaluate in a dev browser
Most hosted browser products look identical in a demo. They diverge on the details that only matter in production. Here is the checklist I would apply before committing.
Protocol fidelity
Does it speak real CDP, or a proprietary RPC that wraps it? If it is real CDP, Playwright's connectOverCDP, Puppeteer's connect, and raw WebSocket clients all work without a vendor SDK. If it is a wrapper, you are locked in. Ask for the endpoint format and test it with a stock client before you write any product code.
Session isolation and persistence
Two separate concerns. Isolation means one session cannot read another's cookies or storage. Persistence means a session can survive a reconnect, or that a profile can be reused across sessions. You want both, configurable per workload. A scraping job wants a fresh profile every time; a logged-in agent wants a durable one.
Viewer and observability
Can you watch the session live? Can you replay it? Can you see console logs and network requests without instrumenting your own code? When an agent fails, the viewer is often the difference between a five-minute fix and a two-hour investigation.
Network configuration
Proxy support, region selection, and configurable browser settings matter for anything touching geo-restricted or bot-sensitive sites. Be precise about what you need: a proxy is not the same as a stealth layer, and neither is a guarantee. Test against your actual targets.
Lifecycle and usage controls
How do you stop a session? What happens if your worker crashes mid-task? Is there a hard timeout? Usage controls let you cap spend and concurrency so a runaway loop does not become a runaway invoice. Check pricing for how metering works on Remote Browser specifically.
Language and framework compatibility
If you use Playwright, Puppeteer, or Selenium today, you should not have to rewrite. CDP compatibility is what makes that possible. Confirm the supported client versions and whether the provider pins Chromium versions you can query.
Wiring a dev browser with Playwright over CDP
The connection pattern is short. You request a session, get a WebSocket endpoint, and hand it to Playwright. The example below uses TypeScript and assumes you have a session endpoint from your provider's API.
import { chromium, type Browser, type Page } from "playwright";
interface SessionInfo {
cdpUrl: string; // wss://... from your provider
sessionId: string;
}
async function openDevBrowser(session: SessionInfo): Promise<{ browser: Browser; page: Page }> {
const browser = await chromium.connectOverCDP(session.cdpUrl, {
timeout: 30_000,
});
// Reuse the existing context if the session already has one,
// otherwise create a fresh page in the default context.
const context = browser.contexts()[0] ?? (await browser.newContext());
const page = context.pages()[0] ?? (await context.newPage());
page.setDefaultTimeout(15_000);
return { browser, page };
}
async function run(session: SessionInfo) {
const { browser, page } = await openDevBrowser(session);
try {
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
const title = await page.title();
console.log("title:", title);
} finally {
// Disconnect the client. This does not necessarily stop the remote session;
// call your provider's stop endpoint when the task is done.
await browser.close();
}
}Three details are worth calling out.
First, connectOverCDP connects to an existing browser; it does not launch one. That means the session's lifecycle is owned by the provider, not by your process. Closing the Playwright client disconnects you, but the remote session may keep running until you explicitly stop it or it hits a timeout. Always pair connect with an explicit stop in your cleanup path.
Second, browser.contexts() may already contain a context if the session was created with a persistent profile. Reusing it preserves cookies and storage. Creating a new context gives you a clean slate. Pick deliberately.
Third, CDP is Chromium-only for Playwright's connectOverCDP. If you need Firefox or WebKit, that is a different transport and a different conversation. The Playwright CDP documentation is the authoritative reference for the client-side behavior.
For the raw protocol underneath, the Chrome DevTools Protocol spec lists the domains and events you can subscribe to directly if you are not using a framework.
Where a dev browser fits in an agent stack
The interesting shift is that agents now consume browsers the way services consume databases. An agent loop looks like: observe the page, decide an action, execute it, repeat. Each step is a CDP round trip. The browser is stateful and long-lived relative to the model call.
That has architectural consequences:
- Session affinity matters. If your agent's browser session is tied to a specific worker, you need sticky routing or a session handle the agent can reconnect to. Stateless request handling does not fit.
- Latency is dominated by the browser, not the model. A page load can take seconds. Parallelism at the session level is how you get throughput, which is why concurrency limits and per-session isolation are first-class concerns.
- Failure is normal. Selectors break, pages change, CAPTCHAs appear. The runtime should make failures observable, not hide them. A viewer plus recorded sessions beats a retry loop you cannot see into.
If you are running an agent that needs to browse the open web rather than a fixed set of endpoints, the runtime choice is effectively a reliability decision. The remote browser online overview covers the operational side of that.
Common mistakes when adopting a dev browser
A few patterns show up repeatedly in teams moving from local Chrome to hosted sessions.
Treating the session as free. Sessions cost money per unit of time. A leaked session from a crashed worker keeps billing until a timeout fires. Set hard timeouts and stop sessions in finally blocks.
Ignoring the viewer until an incident. The viewer is not a nice-to-have. Wire it into your debugging workflow from day one, and log the session ID alongside your task ID so you can find the right recording later.
Assuming stealth is a checkbox. Configurable browser settings and proxies change what a site sees, but no provider can promise you will never be detected. Test against your real targets and measure, rather than trusting a feature list.
Skipping isolation review. If you run multi-tenant workloads, confirm that sessions cannot share storage. Ask how profiles are scoped. This is the kind of thing that is cheap to verify early and expensive to fix later.
Rewriting working code. If your Playwright script works locally, it should work over CDP with a connection change and a cleanup change. If a provider requires a full rewrite, that is a signal about lock-in, not about your code.
When a dev browser is the wrong choice
Not every workload needs one. Skip it if:
- You are writing a one-off script that runs on your machine once.
- Your automation targets a single internal site with no bot sensitivity and no concurrency requirement.
- You need a browser embedded in a desktop app for end users, which is a different product category.
For everything else — agents, CI suites, scraping pipelines, multi-tenant automation — the hosted runtime is usually the lower-maintenance path. The cost is real but predictable, and it replaces a category of operational work you would otherwise own.
Getting started
The fastest way to evaluate a dev browser is to connect a script you already have and see whether it behaves the same. Start with the documentation for session creation and endpoint formats, connect with connectOverCDP, and run one real task end to end. Watch it in the viewer. Then run ten in parallel and see what breaks.
If you want to go deeper on driving a hosted browser from code and agents, remote control browser covers the control-plane details, and remote web browser covers the runtime model. Both are worth reading before you commit to a provider.
The dev browser is not a new category of software. It is the browser, moved to where it can be managed. The teams that get value from it are the ones that treat it as infrastructure — with lifecycle, observability, and cost controls — rather than as a magic endpoint that makes agents work.