Debugging

A breakpoint beats a console.log every time. Elide ships a real debugger for guest code: attach Chrome DevTools to a running script, step through line by line, inspect variables, and evaluate expressions in the paused frame. The same elide run command also collects code coverage and CPU profiles, and the interactive REPL lets you poke at the runtime without writing a file at all.

Quick start

Run a script under the debugger:

bash
 elide run --debugger app.js

Elide enables the Chrome DevTools Protocol (CDP) inspector, prints a connection URL to the terminal, and suspends execution before the first statement so you have time to attach and set breakpoints. Open the printed devtools:// URL in Chrome (or paste the ws:// address into your editor's inspector client) and execution resumes once you're attached.

Running with the inspector

The --debugger flag accepts an optional mode:

bash
 elide run --debugger app.js          # defaults to CDP
 elide run --debugger=cdp app.js      # Chrome DevTools Protocol (explicit)
 elide run --debugger=dap app.js      # Debug Adapter Protocol (for IDEs)

A bare --debugger (or --debugger=auto) selects the default mode, which is CDP (Chrome DevTools Protocol). The flag uses require_equals, so write --debugger=dap, not --debugger dap — that keeps the next argument (your script path) from being swallowed.

—debugger, —profiler, and —coverage work both at the top level and on the run subcommand — elide app.js —debugger and elide run —debugger app.js are equivalent.

When the CDP inspector is active, Elide:

  • Binds the inspector to port 9229.
  • Serves it under a per-session path, /{session}/inspect, where {session} is a short random identifier generated for this run. This makes the endpoint unguessable.
  • Uses your current working directory as the source path, so DevTools can map bundled frames back to your files.
  • Suspends on startup and waits up to 5 minutes for a client to attach before timing out.
The inspector port (9229) is currently fixed and not configurable. Only one debugged script can bind it at a time.
The DAP adapter (—debugger=dap) currently binds 0.0.0.0:4711, which is reachable from other hosts on the network — unlike the CDP inspector, which is effectively localhost-only. Enable DAP only on trusted networks. (jdwp is not a valid —debugger mode and is rejected at the command line.)

Connecting Chrome DevTools

When you launch with --debugger, Elide prints connection instructions including two forms of the address:

1. A devtools://devtools/bundled/js_app.html?ws=localhost:9229/{session}/inspect URL. Open this directly in a Chromium-based browser (Chrome, Edge, Brave) to launch the bundled DevTools frontend already pointed at your session. 2. The raw WebSocket endpoint, ws://localhost:9229/{session}/inspect, for tools that take a CDP WebSocket URL directly.

Alternatively, open chrome://inspect in Chrome, click Configure, ensure localhost:9229 is in the target list, and your Elide target appears under Remote Target. Click inspect to open DevTools.

Once connected you get the standard DevTools debugging experience: breakpoints, step over / into / out, the call stack, scoped variables, watch expressions, and a console that evaluates in the paused frame.

Coverage

Collect code coverage while a script runs:

bash
 elide run --coverage app.js

A bare --coverage (or --coverage=true / --coverage=auto) enables coverage collection. When the script finishes, Elide gathers coverage data from the guest context and renders a report to the terminal.

Profiling

Profile CPU usage with --profiler:

bash
 elide run --profiler app.js                 # CPU tracing (default)
 elide run --profiler=cputracing app.js      # CPU tracing (explicit)
 elide run --profiler=cpusampling app.js     # CPU sampling

A bare --profiler defaults to CPU tracing, which instruments call entry/exit for exact call counts and timings. CPU sampling (--profiler=cpusampling) periodically samples the active stack instead — lower overhead, statistical results. After the run completes, Elide renders the collected profile to the terminal.

Like --debugger, both --profiler and --coverage use require_equals, so always attach the mode with = (e.g. --profiler=cpusampling).

The REPL

For quick experiments, start the interactive REPL:

bash
 elide repl

You can also just run elide with no arguments in an interactive terminal — when stdin is a TTY, Elide drops into the REPL automatically.

The REPL evaluates code through the same runtime as elide run, so the guest web globals you'd expect (fetch, crypto, URL, atob, ReadableStream, and friends) are all available. Results are pretty-printed with syntax coloring, objects and arrays are rendered with structure, and errors are shown with the same boxed renderer used by elide run.

The REPL is polyglot: any guest language installed in your build is available, and top-level bindings you define in one language are mirrored into the others so you can cross-reference values between, say, JavaScript and Python in the same session.

Press Ctrl+C once to interrupt a long-running evaluation; press it again to force-cancel and reset the session.

What's next

  • Connect an IDE -- Wire up the debug protocols and the MCP server from your editor
  • CLI Reference -- All Elide commands and global options