Dape is a Debug Adapter Protocol client written in Emacs Lisp
Debug Adapter Protocol for Emacs
At a glance
- What is it?
- Dape speaks the Debug Adapter Protocol to Emacs, so a debugger written for VS Code can drive a debugging session in Emacs. It ships configurations for GDB, Delve, debugpy and more, works with core Emacs packages only, and deliberately does not read launch.json files.
- Who is it for?
- Dape suits an Emacs user whose language has a debug adapter built for VS Code, since Dape gives them breakpoints, a variable explorer, a REPL and disassembly without leaving Emacs. It is the wrong choice if your debugger is already a native Emacs client such as gud, and its configuration model will not feel familiar if you are coming from VS Code, because launch.json files are explicitly not supported.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 29 days ago.
- What is it written in?
- Mainly Emacs Lisp, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The protocol that makes VS Code debuggers usable elsewhere
Dape is a debug adapter client for Emacs, written in Emacs Lisp and published under GPL-3.0, by Daniel Pettersson. The repository is small and readable, with dape.el as the implementation, dape-tests.el for the tests, a Makefile, a CHANGELOG.org and a README written in Org mode.
The idea is that the debug adapter protocol aims to establish a common API for programming tools, much like the more well-known language server protocol does for things like code completion. Instead of completions, it provides a standardized interface to debuggers. A debug adapter is a separate program that speaks that protocol, and Dape is the client that connects Emacs to it.
That is the whole value proposition. Once a language has a debug adapter written for VS Code, a large and growing set of them, the same adapter can drive a debugging session in Emacs, rather than the user having to fall back on a native Emacs client or, worse, on a terminal.
The documentation says that in theory all debug adapters should be compatible with Dape, and the supported list in the README is long: the vscode-js adapters for JavaScript, Delve for Go, GDB for C, C++, Rust and more, the Microsoft cpptools adapter, lldb-dap for C, C++ and Rust, debugpy for Python, netcoredbg for C#, rdbg for Ruby, the Godot adapter and the JDTLS based adapter for Java.
Starting a session is one command and one name
The interaction model is deliberately small. To begin a debugging session you invoke the dape command, and in the minibuffer prompt you enter a debug adapter configuration name taken from dape-configs.
That minibuffer is where the ergonomics work happens, and the README describes it as a feature rather than an implementation detail. Dape enhances the minibuffer experience by letting you modify or add PLIST entries to an existing configuration using options, and the example given is passing a working directory, a program and a compile command directly on the command line, something like dape-config with a cwd of default-directory, a program path and a compile invocation of gcc with the debug flag.
For a more complete workflow there is a use-package configuration in the README, and the parts of it that matter are the hooks and the custom variables. The keybinding prefix defaults to the same one gud uses, and it can be set to nil if you do not want one. There are hooks to save breakpoints on quit and load them on startup, a global mode for setting breakpoints with the mouse, and settings for the buffer window arrangement, either to the right or in a gud-like layout, and a hook to kill the compile buffer on a successful build.
There is also a project hook for Projectile users that points the working directory at the project root, and a startup hook that saves buffers, which the documentation calls out as useful for interpreted languages.
What the session actually gives you
The feature list is long enough that the arrangement options become the interesting part.
There are log breakpoints and conditional breakpoints, a variable explorer, variable watch, variable hover through eldoc, and a REPL. The interface follows a gdb-mi.el style model, and the window arrangement can be set to put the info buffers on the right or in a gud-like layout, with the gud layout shown paired with corfu as the completion-in-region function.
There is a memory editor backed by hexl, a disassembly viewer, and integration with compile so that a build and a debug session line up. The README also shows rich REPL output and minibuffer adapter configuration hints as separate screenshots, which suggests the REPL is a first class surface rather than a debugging afterthought.
Two things are called out as requirements rather than options. For complete functionality you should enable eldoc-mode in your source buffers, which is what makes variable hover work, and repeat-mode for more pleasant key mappings.
And the dependency situation is worth stating plainly: Dape has no dependencies outside of core Emacs packages, and it tries to get as much out of them as possible.
Why there is no launch.json in Dape
The README has a section on differences with dap-mode, and it is the clearest statement of Dape's design position.
Dape does not support launch.json files. If per project configuration is needed, the answer is to use dir-locals and dape-command instead.
That is a deliberate rejection of the VS Code format, and the reasoning behind it appears in the next bullet: there is no magic and no special variables like ${workspaceFolder}. Instead, functions and variables are resolved before starting a new session.
The stated goal is to try to envision how debug adapter configurations would be implemented in Emacs if VS Code never existed. That is a strong position to take in a project whose whole point is compatibility with VS Code debuggers, and it has a clear cost. Anyone who already has launch.json files for VS Code cannot reuse them, and per project settings have to be expressed in Emacs terms, through dir-locals and dape-command.
The benefit is that the configuration is ordinary Emacs Lisp evaluated in an ordinary Emacs environment, so a project's settings live in the same place and the same language as the rest of its Emacs configuration, and there is no second, VS Code flavoured configuration format to learn.
The adapters you need are separate downloads
Dape is the client, not the debugger, so each supported language needs its own adapter installed, and the README gives per language instructions.
For JavaScript it uses the vscode-js adapters, and you download the js-debug-dap tarball from the vscode-js-debug releases, then unpack it into ~/.emacs.d/debug-adapters with mkdir and tar.
For C and C++ with the Microsoft cpptools adapter, you download the vsix for your platform, unpack it into ~/.emacs.d/debug-adapters/cpptools, and then make two binaries executable, the OpenDebugAD7 and lldb-mi binaries, with chmod +x.
For Python, debugpy is installed with pip. For Go, it is Delve, and the README points at the delve installation and its DAP documentation. For GDB it asks for version 14.1 or newer.
The lldb-dap section shows the macOS route in detail, using the llvm keg from Homebrew, prepending the llvm bin directory to the PATH, and then invoking dape with M-x dape and passing arguments of interest, using the args option for program arguments, the env option for environment variables such as RUST_LOG, and the program option to use something other than a.out, which is what a Rust user needs since the binary lives under target/debug.
The Godot case is configured through the editor settings rather than the adapter itself, under Editor and then Editor Settings and then Debug Adapter.
Building and testing from the Makefile
The Makefile shows how the project is developed, and it is a small file that depends on exactly one external package.
That package is jsonrpc, the JSON-RPC library that Emacs ships as jsonrpc.el, and the rule fetches it from the ELPA package server:
$(JSONRPC):
@curl "https://elpa.gnu.org/packages/$(@D).tar" -o $(@D).tar
@tar -xvf $(@D).tar
@rm $(@D).tarThe .elc rule byte compiles each source file in batch mode, and the check target runs the test suite:
check: $(JSONRPC) $(ELCFILES)
@${EMACS} -Q \
-batch \
-l ert \
--eval="(package-install-file \"$(JSONRPC)\")" \
$(foreach file, $^, -l $(file)) \
-f ert-run-tests-batch-and-exitThe tests are written with ert, which is Emacs Lisp Testing, the framework that ships with Emacs, and the batch invocation means the suite runs without a display.
Dape is also packaged for GNU ELPA, with a badge in the README pointing at the elpa.gnu.org package page, and the repository root has an .elpaignore file for the files that should not go into a package.
The repository has no GitHub releases, so the ELPA package is the distribution route, and the last push was on 2026-09-24.
Editorial conclusion
Dape suits an Emacs user whose language has a debug adapter built for VS Code, since Dape gives them breakpoints, a variable explorer, a REPL and disassembly without leaving Emacs. It is the wrong choice if your debugger is already a native Emacs client such as gud, and its configuration model will not feel familiar if you are coming from VS Code, because launch.json files are explicitly not supported. Before configuring it, read dape-configs to see whether an adapter configuration already covers your language, and enable eldoc-mode and repeat-mode as the documentation recommends.
Frequently asked questions
How do I start a debugging session with Dape?
Invoke the dape command and enter a debug adapter configuration name in the minibuffer, taken from dape-configs. Dape ships pre-defined configurations for several languages, and you can modify or add PLIST entries to an existing configuration from the minibuffer itself.
Does Dape support launch.json files?
No. The README states that Dape does not support launch.json and that for per project configuration you should use dir-locals and dape-command instead, with functions and variables resolved before a session starts rather than through special variables like ${workspaceFolder}.
What do I need before Dape can debug my code?
A debug adapter for your language, installed separately: node plus a vscode-js-debug tarball for JavaScript, Delve for Go, GDB 14.1 or newer for C, C++ and Rust, debugpy installed with pip for Python, and the cpptools vsix unpacked into ~/.emacs.d/debug-adapters for C and C++. You also want eldoc-mode and repeat-mode enabled.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/svaante-dape)Was this useful?