Skip to content

Add debugger support (DAP)#702

Open
TristanSpeakEasy wants to merge 5 commits into
dop251:masterfrom
speakeasy-api:feat/debugger
Open

Add debugger support (DAP)#702
TristanSpeakEasy wants to merge 5 commits into
dop251:masterfrom
speakeasy-api:feat/debugger

Conversation

@TristanSpeakEasy

@TristanSpeakEasy TristanSpeakEasy commented Feb 25, 2026

Copy link
Copy Markdown

This adds debugger support to goja using the Debug Adapter Protocol (DAP), so you can step-debug JavaScript/TypeScript running in goja from VS Code.

The core API lives in debugger.go and vm_debug.go — breakpoints (line, conditional, hit count, log points), stepping, pause, variable inspection, eval while paused, exception breakpoints, and source map support. The DAP server is in a separate debugger/ submodule to keep the go-dap dependency out of the main module.

When no debugger is attached there's zero overhead — everything is gated behind vm.dbg != nil.

The changes to existing files are kept minimal: compiler.go/compiler_expr.go/compiler_stmt.go emit debug variable maps when debugMode is set, runtime.go adds the attach/detach API and CompileForDebug, and vm.go dispatches to the debug-aware execution loop and hooks into save/restore context for frame tracking.

A VS Code extension is included in debugger/vscode-goja-debugger/ with a pre-built .vsix.

Tests: 33 tests for the core debug API in debugger_test.go, 17 DAP integration tests in debugger/server_test.go.

Note: The debugger/go.mod currently has a replace github.com/dop251/goja => ../ directive so it compiles against the local parent module during development. Once this PR is merged, that replace should be removed and the github.com/dop251/goja dependency updated to point at the merged commit (or a tagged release).

@dop251

dop251 commented Jun 3, 2026

Copy link
Copy Markdown
Owner

Hi,

Sorry for not responding earlier. I've had a quick look and here are some thoughts so far:

  1. Everything that's in the debugger folder probably needs to live in a separate repo. I'd like to keep the scope of this one as narrow as possible, and besides I won't be able to maintain the VSCode extension as I'm not using VSCode.
  2. Have you considered making all scopes dynamic when compiling in debug mode? This would move all variables to stash and would generate the name map. This way you wouldn't need makeDebugRegisterNamesMap() and such, and it would simplify the code in general.
  3. I'm a bit concerned about the granularity of the source map. Currently main effort is to make sure exception stack traces are accurate, but debugging may require better granularity. Does it work ok for you?

@TristanSpeakEasy

Copy link
Copy Markdown
Author

Hi @dop251 thanks for getting back to me, unfortunately I won't have the time to address the feedback above or take this forward, so feel free to close this PR or for someone else to pick it up if they want to maintain it.

I can confirm debugging works great with this PR from our experience so far, so I think its a solid base to bring support for debugging via various IDEs if you did decide this is valuable to goja, you would likely just need various pluggins for each IDE you want to target unless they support generic DAP debugging.

I tried not to change the behaviour of goja when debugging is enabled to avoid hiding any issues so you can debug thing as close to ones deployed code as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants