cdp-protocol 0.2.0

A Rust implementation of the Chrome DevTools Protocol
Documentation

cdp-protocol

cdp-protocol exposes the raw, type-safe Chrome DevTools Protocol (CDP) surface area for Rust. The crate is auto-generated from the Chrome 140.0.7339.186 protocol definition and is used by cdp-core, but it can also be consumed directly anywhere you need fine-grained CDP access.

Highlights

  • Complete domain coverage – Every domain published by Chrome at the tracked version is generated into its own Rust module.
  • Strongly typed commands & events – Each command implements cdp_protocol::types::Method, and every CDP event is represented by cdp_protocol::types::Event for ergonomic deserialization.
  • Serde-first design – Structs derive Serialize/Deserialize, so you can plug them into any transport that speaks JSON over WebSocket or Chrome's browser protocol pipes.
  • Version-locked output – Code is produced by the internal gen_cdp generator, keeping the crate synchronized with official Chrome releases.
  • Zero runtime dependencies – Aside from serde/serde_json, no extra dependencies are pulled into your project.

Installation

Add the crate to your Cargo.toml:

[dependencies]
cdp-protocol = "0.1.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Sending commands

Each command struct can be turned into a JSON-RPC payload via the Method trait:

use cdp_protocol::{page, types::Method};
use std::io::Write;

fn navigate<W: Write>(socket: &mut W) -> anyhow::Result<()> {
    let navigate = page::Navigate {
        url: "https://example.com".into(),
        referrer: None,
        transition_type: None,
        frame_id: None,
        referrer_policy: None,
    };

    let call = navigate.to_method_call(1); // 1 == JSON-RPC id; track however you prefer
    let payload = serde_json::to_vec(&call)?;
    socket.write_all(&payload)?;
    socket.write_all(b"\n")?; // depends on your transport
    Ok(())
}

The types::MethodCall helper simply wraps the command with the CDP method name and call id. You can now forward the serialized payload to a WebSocket connected to Chrome's remote-debugging endpoint.

Listening for events

Incoming JSON messages can be parsed into the unified Event enum, making it easy to fan out processing logic:

fn handle_event(raw: &str) -> anyhow::Result<()> {
    match serde_json::from_str::<cdp_protocol::types::Event>(raw)? {
        cdp_protocol::types::Event::PageLoadEventFired(evt) => {
            println!("Page load fired at {:?}", evt.params.timestamp);
        }
        cdp_protocol::types::Event::NetworkRequestWillBeSent(evt) => {
            let url = &evt.params.request.url;
            println!("Network request: {url}");
        }
        _ => {}
    }
    Ok(())
}

Because each domain module re-exports its event payloads, you can drill into strongly typed fields instead of handling raw JSON maps.

Relationship to cdp-core

cdp-core builds a high-level browser automation API on top of this crate. If you need a batteries-included experience (page automation, element handles, networking utilities, etc.), reach for cdp-core. If you want to craft custom CDP flows, integrate with bespoke transports, or experiment with upcoming protocol changes, cdp-protocol lets you work directly with low-level commands.

Updating the protocol definition

The source files in src/ are generated by the internal gen_cdp tool. When Chrome publishes a new stable protocol JSON, re-run the generator and commit the refreshed modules. Keeping the generator inputs in sync ensures the crate's types::Event and domain modules line up with Chrome's expectations.

Contributing & License

  • Contributions are welcome—see the repository-wide CONTRIBUTING.md for guidelines.
  • cdp-protocol is distributed under the MIT License.