What is CDP (Chrome DevTools Protocol): A beginners guide

Kylejeong211 pts0 comments

What is CDP (Chrome DevTools Protocol)? | Browserbase<br>Log in<br>Sign up<br>Get a demo

TLDR; CDP is the control surface that gives external programs access to Chromium’s pages, network stack, JavaScript runtime, input system, debugger, and performance instrumentation.<br>If you open Chrome and press F12 or opt + cmd + i, a panel appears that can inspect a page, watch every network request, execute JavaScript, emulate a phone, and record a performance trace.<br>That panel is a separate process talking to the browser. The language between them is Chrome DevTools Protocol , or CDP.<br>At Browserbase, we’ve learned a lot about the protocol, spending years worth of engineering hours trying to tame it’s imperfections. This is the CDP explainer we wish we had back then.<br>The protocol behind DevTools<br>CDP ships in Chromium-based browsers including Chrome, Edge, Brave, Arc, and Opera. DevTools, Lighthouse, Puppeteer, Playwright, and many browser agents use it to talk to the browser.<br>If your code controls Chromium, CDP is somewhere underneath it.<br>A little history<br>CDP started as the plumbing behind Chrome’s DevTools, not as a general automation API.<br>When Chrome shipped in 2008, its inspector came from WebKit, the rendering engine Chrome (then) shared with Safari. The DevTools front end needed to run separately from the page it inspected, so the team defined a wire protocol between the front end and the browser.<br>┌─────────────────────┐ CDP messages ┌─────────────────────┐<br>│ DevTools front end │ ← commands / events → │ Chromium browser │<br>│ HTML, CSS, JS │ │ renderer, network, │<br>│ │ │ runtime, input │<br>└─────────────────────┘ └─────────────────────┘<br>That WebKit remote debugging protocol became CDP’s ancestor.<br>Then Google split Blink from WebKit in 2013. Chrome’s protocol went with it and became the documented, versioned Chrome DevTools Protocol. Safari continued with the WebKit Inspector Protocol.<br>Headless Chrome and Puppeteer arrived in 2017. Then eventually Playwright generalized browser automation across Chromium, Firefox, and WebKit.

Talk to Chrome yourself<br>Launch Chrome with remote debugging enabled. Use a temporary profile because modern Chrome restricts remote debugging against the default profile.<br>/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \<br>--remote-debugging-port=9222 \<br>--user-data-dir=/tmp/cdp-demo \<br>about:blank<br>Chrome now exposes local discovery endpoints:<br># Run these in a different terminal<br>curl -s | jq .<br>curl -s | jq .<br>The first describes the browser, and the second lists targets you can attach to. A page target includes a webSocketDebuggerUrl, the endpoint for its CDP connection.<br>Using WS you can create a minimal DevTools client:<br>import WebSocket from "ws";

const targets = await fetch("")<br>.then(response => response.json());

const page = targets.find(target => target.type === "page");<br>const socket = new WebSocket(page.webSocketDebuggerUrl);

let id = 0;<br>const send = (method, params = {}) => socket.send(JSON.stringify({<br>id: ++id,<br>method,<br>params,<br>}));

socket.on("open", () => {<br>send("Page.enable");<br>send("Page.navigate", { url: "" });<br>});

socket.on("message", data => {<br>const message = JSON.parse(data);

if (message.method === "Page.loadEventFired") {<br>console.log("Page loaded");<br>socket.close();<br>});

It connects to a page, enables lifecycle events, navigates, and waits for Chrome to announce that the page loaded.<br>The rest of CDP is similar, just at a much larger scale.<br>The semantics of CDP<br>CDP uses JSON messages, typically carried over a WebSocket or pipe. The protocol is divided into domains like Page, Network, Runtime, Input, Target, Accessibility, and Tracing.<br>Each of these domains owns part of the browser.<br>Page handles navigation.<br>Network observes requests and responses.<br>Runtime evaluates JavaScript.<br>Target discovers pages, frames, and workers.<br>Tracing records performance data.

A command asks Chrome to do something:<br>{"id": 1, "method": "Page.navigate", "params": {"url": ""}}<br>Chrome returns a response with the same ID and the result:<br>{"id": 1, "result": {"frameId": "...", "loaderId": "..."}}

The ID lets a client keep many commands in flight and match each response to its request.<br>Events travel the other way. Chrome emits them whenever browser state changes:<br>{"method": "Network.requestWillBeSent", "params": {}}<br>{"method": "Page.frameNavigated", "params": {}}<br>{"method": "Runtime.executionContextCreated", "params": {}}

Events have no request ID. To read them, enable a domain then consume its event stream.<br>CDP commands are questions or instructions, and events are the browser responding.

Sessions and targets<br>Think of CDP connection as a tree.

The root of this tree is the browser. From there, you discover and attach to targets.<br>A target is something Chrome can inspect or control: a page, an out-of-process iframe, a service worker, a shared worker, or an extension page.<br>Attaching to a target creates a session. Commands sent through that session affect that target and its events return through the same...

chrome page protocol browser devtools target

Related Articles