How JSAR Integrates with Chrome DevTools: Complete CDP Implementation Guide
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. 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) 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) 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 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.
// 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:
// 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:
// 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 and 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:
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.
Summary
- Full CDP Support: JSAR implements the Chrome DevTools Protocol through
CdpHandler(host) andContentCdpHandler(content) coordinators, enabling standard debugging clients to connect via WebSocket. - Multi-Process Architecture: The
ContentDomainProxyroutes debugging commands across process boundaries using theTrInspectorIPC channel withTrCdpRequestandTrCdpResponsemessages. - Domain Coverage: Built-in support for
Runtime,Log, andDOMdomains allows JavaScript debugging, console capture, and document inspection, with implementations located insrc/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/protocolendpoint provides the complete CDP schema, while WebSocket connections are available atws://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.
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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →