Nushell Debugger
Step-debug Nushell scripts in VS Code — breakpoints,
stepping, a five-scope variable view, rich visualizers, and interactive
prompts that become native VS Code dialogs.
Quick start
- Open a
.nu file.
- Set breakpoints in the gutter.
- Press F5 (no
launch.json needed — the active file is debugged).
If your script's def main takes required arguments, you'll be prompted for
them at launch; you can also set "args" in launch.json. If the script has
no main, you're offered its functions to pick an entry point (or run it
top-to-bottom) — or set "entryPoint" in launch.json.
Features
Breakpoints
- Verified breakpoints: a breakpoint on a blank/comment line snaps to the
next executable line.
- Conditional breakpoints — any nu expression:
$total > 4000.
- Logpoints —
file {$f.name} running total {$total} prints without
stopping.
- Exception breakpoints ("Runtime errors" filter): pause at the raising
line with the error message in the dialog. When an external command fails,
its stderr tail is attached — you see what it complained, not just the
exit code.
Stepping
- F10 steps a whole line; F11 steps into nu code (closures —
including bodies on the same line — and custom commands).
- On builtin pipelines, F11 walks pipe stages: it stops at every command
boundary and the Pipeline scope shows
in → <command> — the exact value
about to flow into that stage.
Variables — five scopes
| Scope |
Contents |
| Locals |
return (the latest expression/command result) first, then variables, custom-command parameters and flags (absent switches show false, defaults apply), and $in inside closures |
| Pipeline |
in → command — the current pipe-stage input |
| Globals |
nushell special variables — $nu (config/paths/pid/os-info) and $env (incl. runtime $env.X = … mutations) — as records |
| Registers |
the IR evaluator's raw slots (pairs with the IR panel) |
| Process |
rolling stdout/stderr tails of external commands |
Inspection is depth-unlimited (children load on demand), previews are
structured ([table 3 rows], {name: a.txt, …}, 0x[de ad …]), and
streams describe themselves (<byte stream: text from external command>).
Visualizers
Right-click any variable → Visualize:
- tables → sortable, filterable grids
- records/lists → sortable key/value and indexed tables
- binary → hex view with 1/2/4/8/16/32/64-byte grouping and LE/BE tooltips
- strings → JSON/XML auto-detected, formatted, syntax-highlighted
Visualizing a top-level variable pins it: the panel refreshes on every stop.
Watch, hover & Debug Console
Real nu expressions evaluated against the captured variables:
$files | where size > 1000 works while paused. The console can run
externals too — handy for re-running a pipeline stage to inspect data that
only exists as a stream.
Interactive prompts
input and input list become native VS Code dialogs (input box /
quick pick, --multi and --index supported). The script blocks until you
answer; Esc returns nothing.
Time-travel
Recording is on by default — just debug, then use the Step Back and
Reverse Continue toolbar buttons to walk backward through execution:
revisit any line the script ran through (even inside a command call), and see
what the variables were at that moment. It's a recorded timeline you scrub, so
you're inspecting the past, not re-running it — you can't change the past and
continue differently; stepping forward past "now" resumes real execution.
Older steps drop once the ring buffer fills (nuDap.timeTravelMaxSteps);
nuDap.timeTravel: false records only at stops. In a past view you see Locals
and Globals (Pipeline/Registers/Process are live-only).
Hot restart
The Restart button re-runs the (possibly edited) script from disk in the
same session, breakpoints intact. Enable nuDap.restartOnSave for an
edit → save → back-at-breakpoint loop.
IR panel
"Nushell Debug: Show IR" shows the compiled instruction listing of the
block you're paused in, with the current instruction highlighted — updates
as you step.
Settings
| Setting |
Default |
Description |
nuDap.adapterPath |
(bundled) |
Path to a custom nu-dap adapter binary |
nuDap.restartOnSave |
false |
Restart the active debug session when a .nu file is saved |
nuDap.timeTravel |
true |
Record every executed line so Step Back / Reverse Continue can revisit any line; false records only at stops |
nuDap.timeTravelMaxSteps |
10000 |
Ring-buffer cap on recorded steps (Reverse goes back at most this many) |
Good to know
- The extension bundles its own nushell engine (0.114.1); scripts are
debugged against that version, not your installed
nu.
- At a stop, the highlighted line has not executed yet — on
for f in $files, $f updates when you step into the body.
- Variables assigned from streaming pipelines show a stream description —
reading a stream would consume the program's data.
- Closure parameters (
each {|n| …}) aren't listed in Locals (the element
is visible as in); input listen and editing variables while paused are
not supported yet.
- Externals get NUL as stdin: a child that waits for terminal input sees
EOF instead of hanging the session.
License
MIT