LUA DEBUGGER — DEBUG ADAPTER PROTOCOL SERVER

Moonwalk
OVERVIEW
Moonwalk is a cross-platform Lua debugger and Debug Adapter Protocol server. It is built for a native, plugin-free Neovim debugging workflow while remaining compatible with Visual Studio Code and other Debug Adapter Protocol clients. Moonwalk is not an nvim-dap wrapper, and it does not require users to install a Neovim debugging plugin: the debugger core is editor-independent, and the Neovim integration is implemented with native Lua, Neovim APIs, and direct DAP communication. It debugs Lua 5.1–5.4 and LuaJIT targets — local processes, Neovim processes, and remote processes — on Linux, macOS, Windows, Windows Subsystem for Linux, Android, NetBSD, and FreeBSD.
HOW IT WORKS
- 1A native DAP registry or direct vim.debug-based client selects Moonwalk when the active buffer has the lua filetype, and registers the Lua adapter once with require("dap.lua").setup(). No nvim-dap, nvim-dap-ui, mason.nvim, or other third-party debugging plugin is involved at any point. Source: Moonwalk README, 'Native Neovim configuration'.
- 2The client spawns the moonwalk executable and opens a Debug Adapter Protocol session: initialize, then a launch request (program, cwd, stopOnEntry, luaVersion, and the rest of the launch schema in CONFIGURATION below) or an attach request against a running process. Source: Moonwalk README, 'Command model' architecture diagram; extension/package.json debugger contribution.
- 3Moonwalk's proxy process passes the launch parameters to the debuggee and loads luadebug into the Lua virtual machine — by the standard -e argument or by injection. Parameter delivery happens in two stages: some parameters at initialization, then all of them again with the DAP initialized event. Source: Moonwalk docs/DebuggerInit.md.
- 4The client sets breakpoints with setBreakpoints and signals configurationDone; the VM then runs under the debugger — line, function, conditional, and hit-count breakpoints, logpoints, exception breakpoints, stepping, stack frames, scopes and variables, watches, and expression evaluation. Source: Moonwalk README, 'Features'; docs/capabilities.md capability table.
- 5Session events (stopped, output, terminated) flow back over the same DAP connection, and the editor renders debugging state with its own native signs, extmarks, windows, and buffers. In Neovim the generic debugger commands (:DebugRun, :DebugStepInto, …) are mapped buffer-locally in Lua buffers only, so the same key vocabulary serves other adapters in other filetypes. Source: Moonwalk README, 'Lua buffer mappings' and 'Command model'.
- 6The same adapter serves any DAP client unchanged — VS Code included — because the core is editor-independent; Neovim-specific discovery (adapter path, runtime path, process selection) lives in the Lua-specific :LuaDebug* commands, kept separate from the generic command model. Source: Moonwalk README, 'Command model'.
CONCEPTS
CONFIGURATION
| Option | Default | What it does |
|---|---|---|
program | ${workspaceFolder}/main.lua | Lua program to debug — the path of the script (launch). Source: extension/package.json launch schema. |
cwd | ${workspaceFolder} | Working directory at program startup (launch). Source: extension/package.json launch schema. |
stopOnEntry | false | Automatically stop after entry (launch and attach). Source: extension/package.json schemas. |
stopOnThreadEntry | true | Automatically stop after thread entry (launch and attach). Source: extension/package.json schemas. |
luaVersion | lua54 | Default Lua version of the debug target (launch and attach). Source: extension/package.json schemas; extension/package.nls.json. |
console | integratedTerminal | The console to launch the program in: internalConsole, integratedTerminal, or externalTerminal (launch). Source: extension/package.json launch schema; extension/package.nls.json. |
arg | [] | Command-line arguments arg[1] … arg[n] passed to the program (launch). Source: extension/package.json launch schema. |
env | object whose default sets PATH to ${workspaceFolder} | Environment variables passed to the program; a null value removes the variable (launch). Source: extension/package.json launch schema. |
path | ${workspaceFolder}/?.lua | Search path for Lua programs in the debuggee (launch). Source: extension/package.json launch schema; extension/package.nls.json. |
cpath | ${workspaceFolder}/?.so | Search path for native libraries in the debuggee (launch). Source: extension/package.json launch schema; extension/package.nls.json. |
skipFiles | [] | Glob patterns for files to skip when debugging (launch and attach). Source: extension/package.json schemas. |
sourceMaps | [['./*', '${workspaceFolder}/*']] | Pairs mapping the source paths of the remote host to local paths (launch and attach). Source: extension/package.json schemas. |
outputCapture | [] | Where output messages are captured from: print, or the stdout/stderr streams (launch and attach). Source: extension/package.json schemas. |
address | not stated in source | Debugger address for attach: an IPv4 or IPv6 address with port, or a Unix domain socket (attach). Source: extension/package.json attach schema. |
processId | ${command:pickProcess} | Id of the process to attach to (attach). Source: extension/package.json attach schema. |
processName | lua.exe | Name of the process to attach to (attach). Source: extension/package.json attach schema. |
inject | gdb | How the debugger is injected into the target (launch and attach). Source: extension/package.json schemas. |
CONTROLS
| Action | Control |
|---|---|
| Run / continue | :DebugRun / :DebugContinue — Lua buffers: <F5> |
| Pause | :DebugPause — Lua buffers: <F6> |
| Run last configuration | :DebugRunLast — Lua buffers: <F7> |
| Terminate | :DebugTerminate — Lua buffers: <F9> |
| Toggle breakpoint | :DebugBreakpoint — Lua buffers: <F8> / <leader>db |
| Conditional breakpoint | :DebugBreakpointCondition — Lua buffers: <leader>dB |
| Logpoint | :DebugLogpoint — Lua buffers: <leader>dl |
| Step over | :DebugStepOver — Lua buffers: <F10> |
| Step into | :DebugStepInto — Lua buffers: <F11> |
| Step out | :DebugStepOut — Lua buffers: <F12> |
| Restart | :DebugRestart — Lua buffers: <leader>dR |
| Evaluate expression (hover) | :DebugHover — Lua buffers: <leader>dh |
| Scopes | :DebugScopes — Lua buffers: <leader>ds |
| Debug REPL | :DebugRepl — Lua buffers: <leader>de |
| Session status | :DebugStatus — Lua buffers: <leader>dq |
| Show the Lua adapter path | :LuaDebugAdapter — Lua buffers: <leader>dmA |
| Check the Lua environment | :LuaDebugCheck — Lua buffers: <leader>dmC |
| Select a Lua process | :LuaDebugProcess — Lua buffers: <leader>dmP |
| Show the Lua runtime path | :LuaDebugRuntime — Lua buffers: <leader>dmR |
BENCHMARKS
| Measurement | Median | Runs |
|---|---|---|
| Launch → first breakpoint stopped | 104.7 ms | 10 |
| Stepping (next × 200 per run) | 24.7 steps/s | 5 |
| loop.lua plain (bundled Lua 5.4, spawn → exit) | 2.24 ms | 10 |
| loop.lua under Moonwalk, no breakpoints (launch → terminated) | 130.1 ms | 10 |
NOT COVERED
- The sources read document the build (luamake; luamake -mode release for release) but do not state an end-user installation step for the built adapter — where the moonwalk executable and its runtime tree land after a build is not stated in source. The BENCHMARKS harness for this page ran the release tree as built in-tree under the repo's publish/ directory. - Lua 5.5 is explicitly not supported: the README states it must not be advertised until Moonwalk has an implemented, tested, and documented compatibility path for it. - docs/capabilities.md marks several DAP capabilities 'No (LuaDebug)' or 'No (VSCode)' — among them supportsStepBack, supportsDataBreakpoints, supportsCompletionsRequest, and supportsBreakpointLocationsRequest. Those are inherited limits of the LuaDebug core or the VS Code client as that table records them; they are not re-derived here. - Moonwalk is not published on LuaRocks (verified 2026-10-18), which is why it is classed with the Apps rather than the Packages; no rock or package-manager install command is claimed. - The project publishes no performance figures of its own. The BENCHMARKS table on this page was measured for this site, with the method stated in the table's note — it is not taken from the repository.
REFERENCES
- Debug Adapter Protocol — specificationThe protocol Moonwalk implements: the initialize, launch, setBreakpoints and configurationDone requests and the stopped and terminated events the diagram and the benchmarks on this page speak in.
- Moonwalk — DAP capability table (docs/capabilities.md)The adapter's own record of which DAP capabilities are supported, and which are marked 'No (LuaDebug)' or 'No (VSCode)'.
- Lua 5.4 — reference manualThe manual for the newest Lua version Moonwalk targets; the debug library (lua_Debug, hooks) documented there is the mechanism a Lua debugger is built on. Manuals for 5.1–5.3 are linked from lua.org.
- LuaJIT — the LuaJIT projectThe second runtime family Moonwalk debugs, alongside PUC Lua 5.1–5.4.