Introduction to Chrome DevTools Protocol

What is CDP?

The Chrome DevTools Protocol (CDP) is a debugging interface that enables inspection, monitoring, and control of Chromium, Chrome, and other Blink-based browsers. The protocol is maintained by the Chrome DevTools team and serves as the foundation for tools like Chrome DevTools and Puppeteer.

Using CDP

When you open Chrome DevTools, you are indirectly using CDP. A more direct way to observe it is to open DevTools on the DevTools window itself. This can be done by:

  1. Setting DevTools to open in a separate window (dock side, select first option).
  2. Pressing Ctrl+Shift+I (or Cmd+Opt+I on macOS) on the DevTools window to open a second instance.

The URL of this second DevTools instance will be in the format devtools://devtools/bundled/.... Within its console, you can execute CDP commands directly, such as:

let Main = await import('./main/main.js');
Main.MainImpl.sendOverProtocol('Runtime.evaluate', {expression: "alert(12345)"});

This will trigger an alert dialog in the inspected page, demonstrating how console evaluations are routed through CDP to the browser's JavaScript engine.

The Protocol Monitor tool in DevTools also provides a visual interface for observing CDP traffic.

Key Debugging URLs

When a browser instance is launched with remote debugging enabled (e.g., via the --remote-debugging-port flag), two HTTP endpoints become available:

  • http://localhost:[port]/json/list
  • http://localhost:[port]/json/version

The /json/list endpoint returns a JSON array containing information for each open tab or target. A typical response includes:

[
  {
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:8080/...",
    "id": "a31c4d5c-b0df-48e8-8dcc-7c98964e2ebe",
    "title": "",
    "type": "page",
    "url": "http://example.com",
    "webSocketDebuggerUrl": "ws://localhost:8080/devtools/page/a31c4d5c-b0df-48e8-8dcc-7c98964e2ebe"
  }
]

The webSocketDebuggerUrl field provides the WebSocket address needed to establish a direct CDP connection to that target.

Connecting via WebSocket

Once you have the WebSocket URL, you can connect and send CDP commands programmatically. Below is an example using Node.js with the ws library and Puppeteer.

const WebSocket = require('ws');
const puppeteer = require('puppeteer');

(async () => {
  // Launch browser with remote debugging enabled
  const browser = await puppeteer.launch();
  const wsEndpoint = browser.wsEndpoint();

  // Establish WebSocket connection
  const socket = new WebSocket(wsEndpoint, { perMessageDeflate: false });
  await new Promise(resolve => socket.once('open', resolve));
  console.log('WebSocket connected');

  socket.on('message', data => console.log('Received:', data));

  // Send a CDP command
  socket.send(JSON.stringify({
    id: 100,
    method: 'Target.setDiscoverTargets',
    params: { discover: true }
  }));
})();

JSON-RPC Message Format

CDP uses a JSON-RPC-like format over WebSocket. Each command consists of an id, a method, and params. For example, to evaluate JavaScript in the target context:

{
  "id": 235,
  "method": "Runtime.evaluate",
  "params": {
    "expression": "console.log('hello');",
    "objectGroup": "console",
    "includeCommandLineAPI": true,
    "silent": false,
    "contextId": 1,
    "returnByValue": false,
    "generatePreview": true,
    "userGesture": true,
    "awaitPromise": false
  }
}

Chrome DevTools and other clients compose such messages to perform a wide range of operations—from DOM inspection to performence profiling.

References

Tags: Chrome DevTools Protocol WebSocket Remote Debugging JSON-RPC Puppeteer

Posted on Sat, 15 Aug 2026 16:38:13 +0000 by zack45668