# How JSAR Integrates with Chrome DevTools: Complete CDP Implementation Guide

> JSAR natively integrates with Chrome DevTools via a full CDP implementation. Debug host and content processes using its WebSocket endpoint. Learn how to set it up.

- Repository: [M Creative Lab/jsar-runtime](https://github.com/m-creativelab/jsar-runtime)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Yes, JSAR provides native Chrome DevTools integration through a full Chrome DevTools Protocol (CDP) implementation that exposes a WebSocket endpoint for debugging both host and content processes.**

The `m-creativelab/jsar-runtime` repository includes a production-ready inspector system that allows any CDP-compatible client—including Chrome DevTools, VS Code, or custom debugging tools—to connect to running JSAR instances for live JavaScript debugging, DOM inspection, and runtime profiling.

## Understanding the JSAR Chrome DevTools Architecture

The JSAR Chrome DevTools integration uses a multi-process architecture that separates host-side coordination from content-process execution. This design ensures that debugging operations do not block the main runtime while maintaining full observability into JavaScript execution contexts.

### Host-Process CDP Coordinator

At the core of the integration is the **`CdpHandler`** class, defined in [`src/runtime/inspector/cdp_handler.hpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/runtime/inspector/cdp_handler.hpp). This per-client coordinator manages the lifecycle of individual DevTools connections by parsing incoming JSON-RPC messages, routing them to appropriate domain handlers, and aggregating responses. When a debugging client connects via WebSocket, the inspector client instantiates a dedicated `CdpHandler` instance to manage that session.

### Content-Process Proxy Layer

For operations targeting content processes, the **`ContentDomainProxy`** ([`src/runtime/inspector/content_domain_proxy.hpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/runtime/inspector/content_domain_proxy.hpp)) acts as an intermediary. This component maintains a reference to the host `CdpHandler` and forwards CDP requests to the appropriate content-process coordinator through an IPC-based inspector channel. The proxy handles serialization of `TrCdpRequest` and `TrCdpResponse` messages across process boundaries.

### Content-Process Coordinator

Within each content process, the **`ContentCdpHandler`** ([`src/client/inspector/content_cdp_handler.hpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/client/inspector/content_cdp_handler.hpp)) registers domain-specific handlers such as `Runtime`, `Log`, and `DOM`. This coordinator receives forwarded requests from the host process, executes them against the live JavaScript context, and returns results back through the proxy layer.

## Key Components of the JSAR Inspector System

The integration relies on several specialized components working together to provide a seamless debugging experience.

**Domain Handlers** implement the actual CDP method logic. Each supported domain resides in `src/client/inspector/domains/` and includes implementations like `CdpRuntimeDomain` for JavaScript execution contexts, `CdpLogDomain` for console output, and `CdpDomDomain` for document inspection. These handlers process method calls such as `Runtime.enable`, `Log.entryAdded`, and `DOM.getDocument`.

**IPC Communication** occurs through the `TrInspector` channel, which transports serialized CDP messages between host and content processes. The protocol uses three message types: `TrCdpRequest` for outgoing commands, `TrCdpResponse` for results, and `TrCdpEvent` for asynchronous notifications like console logs or breakpoint hits.

**WebSocket Endpoint** exposes the debugging interface at `ws://localhost:<port>/devtools/inspector/{content_id}`. The server implementation in [`src/runtime/inspector/inspector_client.cpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/runtime/inspector/inspector_client.cpp) handles client connections and protocol upgrades. Additionally, the `/json/protocol` HTTP endpoint returns the complete CDP schema describing all supported domains and methods.

## How to Connect to JSAR with Chrome DevTools

Connecting to a running JSAR instance requires establishing a WebSocket connection to the inspector endpoint and enabling the desired CDP domains.

```javascript
// Connect to the JSAR inspector endpoint
// Replace <port> and <content_id> with values from /json/list
const ws = new WebSocket('ws://localhost:9423/devtools/inspector/1');

ws.onopen = () => {
  // Enable the Runtime domain to capture execution contexts
  ws.send(JSON.stringify({
    id: 1,
    method: 'Runtime.enable',
    params: {}
  }));
};

ws.onmessage = (event) => {
  const reply = JSON.parse(event.data);
  console.log('CDP reply:', reply);
};

```

The connection process involves querying the `/json/list` endpoint to discover active content processes, then targeting the specific `content_id` representing the JavaScript context you wish to debug. Once connected, you can issue CDP commands to control breakpoints, evaluate expressions, or inspect heap state.

## Debugging JavaScript and DOM in JSAR

The JSAR inspector supports real-time logging and DOM manipulation through standardized CDP domains.

To capture console output from the JavaScript runtime, enable the Log domain:

```javascript
// Enable Log domain to receive console events
ws.send(JSON.stringify({ id: 2, method: 'Log.enable', params: {} }));

// When the application logs an error, DevTools receives:
{
  "method": "Log.entryAdded",
  "params": {
    "entry": {
      "source": "javascript",
      "level": "error",
      "text": "Uncaught TypeError: undefined is not a function",
      "timestamp": 1697056323.123,
      "url": "file://app.js",
      "lineNumber": 42
    }
  }
}

```

For DOM inspection, enable the DOM domain and request the document structure:

```javascript
// Enable DOM domain
ws.send(JSON.stringify({
  id: 3,
  method: 'DOM.enable',
  params: {}
}));

// Request the document root
ws.send(JSON.stringify({
  id: 4,
  method: 'DOM.getDocument',
  params: {}
}));

```

The response contains the complete node tree with node IDs, allowing subsequent operations like `DOM.querySelector` or `DOM.setAttributeValue`. The domain logic resides in [`src/client/inspector/domains/cdp_dom_domain.hpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/client/inspector/domains/cdp_dom_domain.hpp) and [`cdp_dom_domain.cpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/cdp_dom_domain.cpp).

## Optional Build Configuration

The Chrome DevTools integration is optionally compiled using the **`TR_ENABLE_INSPECTOR`** preprocessor macro. This allows production builds to exclude all inspector-related code, eliminating the WebSocket server, IPC channels, and domain handlers to reduce binary size and attack surface. When this macro is undefined, the `CdpHandler` and `ContentDomainProxy` classes are not instantiated, and no debugging endpoints are exposed.

To retrieve the complete protocol schema for your specific JSAR build, query the discovery endpoint:

```bash
curl http://localhost:9423/json/protocol

```

This returns a JSON object describing all available domains, including custom JSAR-specific extensions like `JSAR.UniversalRenderingServer`, along with their method signatures and event definitions. The schema is assembled by `CdpHandler::addProtocolDefinitions()` in [`src/runtime/inspector/cdp_handler.cpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/runtime/inspector/cdp_handler.cpp).

## Summary

- **Full CDP Support**: JSAR implements the Chrome DevTools Protocol through `CdpHandler` (host) and `ContentCdpHandler` (content) coordinators, enabling standard debugging clients to connect via WebSocket.
- **Multi-Process Architecture**: The `ContentDomainProxy` routes debugging commands across process boundaries using the `TrInspector` IPC channel with `TrCdpRequest` and `TrCdpResponse` messages.
- **Domain Coverage**: Built-in support for `Runtime`, `Log`, and `DOM` domains allows JavaScript debugging, console capture, and document inspection, with implementations located in `src/client/inspector/domains/`.
- **Optional Compilation**: The entire inspector system can be excluded from builds by undefining `TR_ENABLE_INSPECTOR`, removing all debugging overhead for production deployments.
- **Protocol Discovery**: The `/json/protocol` endpoint provides the complete CDP schema, while WebSocket connections are available at `ws://localhost:<port>/devtools/inspector/{content_id}`.

## Frequently Asked Questions

### Does JSAR support all Chrome DevTools features?

JSAR implements core CDP domains including `Runtime`, `Log`, and `DOM` for JavaScript execution, console output, and document inspection. However, not all Chrome DevTools features are available—domains like `Profiler` or `HeapProfiler` may have limited implementation depending on the specific JSAR version. Check the `/json/protocol` endpoint on your running instance to see the exact list of supported methods and events.

### How do I find the WebSocket URL for a JSAR content process?

Query the `http://localhost:<port>/json/list` endpoint to receive a JSON array of available debugging targets. Each entry includes a `webSocketDebuggerUrl` field containing the full WebSocket URL with the correct `content_id`. The port defaults to 9423 but may be configured during runtime initialization in [`src/runtime/inspector/inspector_client.cpp`](https://github.com/m-creativelab/jsar-runtime/blob/main/src/runtime/inspector/inspector_client.cpp).

### Can I disable the inspector in production builds?

Yes. The inspector system is conditionally compiled using the `TR_ENABLE_INSPECTOR` macro. When this macro is undefined during compilation, the `CdpHandler`, `ContentDomainProxy`, and all domain handlers are excluded from the binary, and no WebSocket server or HTTP endpoints are created. This eliminates debugging capabilities but reduces memory footprint and security exposure.

### What CDP domains are implemented in JSAR?

According to the source code in `src/client/inspector/domains/`, JSAR implements standard domains including `Runtime` (JavaScript contexts), `Log` (console events), and `DOM` (document structure). Additionally, JSAR provides custom domains such as `JSAR.UniversalRenderingServer` for engine-specific debugging. The complete schema is available through the protocol discovery endpoint or in the documentation at [`docs/internals/CDP_SUPPORT.md`](https://github.com/m-creativelab/jsar-runtime/blob/main/docs/internals/CDP_SUPPORT.md).