Debugger
Debug Node.js, TypeScript, Python, Go, .NET and Java from the Run dock or the IDE, on any host, on desktop and in the portal.
- Topic
- Editor & IDE
- Available on
- Available onDesktopWeb Portal
- Reviewed
- October 15, 2026
On this page
Glueprint has a built-in debugger for Node.js and TypeScript (including front-end code in Google Chrome or Microsoft Edge), Python, Go, .NET and Java. It drives each runtime’s standard debugger over the Debug Adapter Protocol (DAP), installs a missing debugger for you, and works the same on this computer, on the other hosts of your organization, and in the web portal.
Where the debugger lives
- The Debug tab sits in the workspace’s Run dock, next to Run. A dot on the tab shows when a session is running or paused. The tab holds the launch picker and the controls (Continue or Pause, Step Over, Step In, Step Out, Restart and Stop), a banner that says why and where the program paused, and five views: Variables, Watch, Call Stack, Breakpoints and Console (with a count of unread output). An ended session stays in the tab until you Close it.
- The Debug pane sits in the IDE sheet, under Files and Search. Collapse it from its header and drag its top edge to resize it. It opens by itself when a session of that worktree starts or pauses (for a workspace on another host, only a session started from this window), and never closes by itself. Pressing Esc in one of its text fields, such as a watch expression, keeps the IDE sheet open. Esc on another Debug control closes the sheet.
- The floating toolbar appears at the top of the window while a session runs, with the same controls and the paused location, which opens the file. While the IDE sheet is open, a copy sits in the sheet.
- The Debug chip in the status bar lists every session with Show, Continue and Stop. Debug: Show Debug View in the command palette brings up the Debug tab of the workspace on screen.
When a session pauses, the editor jumps to the paused line: in the IDE sheet when it is open on that workspace, in the file’s tab when the workspace has one open, otherwise by opening the IDE sheet for the workspace on screen. A pause in a workspace that is not on screen shows in the chip and the toolbar; click its location to go there. A frame that has no source file reads “Source not available”. For a workspace on another host, only a session started from this window moves the editor (see Remote hosts below).
Start debugging
When the Debug tab has no session, it offers:
- Debug current file, for the file open in the workspace (the IDE sheet’s file while the sheet
is open, else the focused file tab):
- non-test
.js,.mjs,.cjs,.ts,.mtsand.ctsfiles run under Node.js, from the workspace root; .pyfiles run under debugpy;- a
.gofile debugs its package, and a_test.gofile runs that package’s tests; - JavaScript and TypeScript
*.test.*or*.spec.*files use a covering Vitest or Jest launch configuration for Debug this test (including.jsxand.tsxtests; see TypeScript below); - other front-end files (
.tsx,.jsx,.vue,.svelte) are refused with “Front-end files run in the browser: use Debug in browser.”
- non-test
- Debug in browser entries (
localhost:<port>), one for each dev server this worktree is serving (see Browser debugging below). - Generate launch configurations, which adds configurations for the projects it recognizes and says how many it added.
- Open launch.json (labelled
.vscode/launch.jsonwhen the configurations come from VS Code’s file), or Create launch.json, which writes a commented starter file and opens it. - Breakpoints, the workspace’s breakpoints, with Remove all.
To start a configuration, pick it in the launch picker and press Start, or press F5 (F8 in
the portal). The key works anywhere in the workspace outside a text field or a terminal. It
continues a paused session; otherwise it starts the configuration you last started in that
workspace, else the first one, else Debug current file. It starts the workspace of the Debug view or
the editor you are in, else the workspace on screen. The picker and F5 pass the open file to the
configuration’s ${file} variables.
Restart stops the session and starts its configuration again, with the same file. After the app reloads, only a session on another host can be restarted (its host still knows the configuration and the file). Stopping a session while it is still starting is not an error. Debug current file, Debug this test and Debug in browser are never remembered as the workspace’s choice.
Launch configurations
Glueprint reads .glueprint/launch.json at the workspace root. Without one it reads
.vscode/launch.json instead (see VS Code configurations below). Comments and trailing commas are
allowed. Entries use VS Code’s shape: name, type, request (launch or attach), program,
args, cwd, env and the debugger’s own keys. type picks the debugger (see Debug adapters
below), and a windows, osx or linux block is merged over the entry on that platform.
.glueprint/launch.json declares "version": "0.1", or no version at all:
{
"version": "0.1",
"configurations": [
{
"name": "Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/server.ts"
}
]
}
- Variables.
${workspaceFolder}(and VS Code’s older${workspaceRoot}),${workspaceFolderBasename},${cwd},${pathSeparator}and${env:NAME}resolve before the launch.${file},${relativeFile},${fileDirname}and${fileBasenameNoExtension}name the file open in the editor when you start; a configuration that uses one with no file open fails and names the variable.${command:...}and${input:...}are never resolved. - Working directory. A program with no
cwdruns in the workspace root. - Pre-launch tasks.
preLaunchTasknames a Run dock task (from.glueprint/tasks.json, package scripts or any other source the dock discovers). It runs in the Run dock on the workspace’s host, with its output in its own tab. A one-shot task must exit cleanly; a long-running task (a dev server, a watcher) counts as done once it reports ready, and one that is already running is reused. Debugging then starts and the dock returns to the Debug tab. If the task fails, the dock stays on its tab and both the tab and the Debug view say why. There is no time limit: Stop task in the notice ends the wait. - Console. Program output goes to the Console view. Node.js, Python and Java launches always use
the internal console, even when
consoleasks for a terminal ("integratedTerminal"); Node.js and Python print a note saying so. - Files outside the workspace. Glueprint never reads or writes a launch file that resolves
outside the workspace, for example in a worktree whose
.glueprintfolder is a symlink into the main checkout. The launch picker shows the error; make.glueprinta real folder in that worktree.
Generated configurations
Generate launch configurations adds to .glueprint/launch.json, creating it when needed, and
keeps your comments, key order and formatting; a name that already exists is skipped. It
recognizes:
- Node.js, in the root package and its workspace members: each package’s
main(a library’smain, one declared next totypes, is skipped) and itsdevandstartscripts throughnpm. Amainbuilt intodist,buildoroutgets the package’sbuildscript as itspreLaunchTask, and in a TypeScript packageoutFilesfromtsconfig.json’soutDir. A TypeScript entry gets a direct launch when tsx is installed. Vitest and Jest packages get “current file” test configurations. Avite.config.*adds a Chrome launch on itsserver.port(else 5173) and anext.config.*one on 3000; dev server launches have nopreLaunchTask. - Python: a Django
manage.py(runserver --noreload), a package’s__main__(also in asrclayout), thenmain.pyorapp.py, with the project’s.venvorvenvinterpreter. - Go: one launch per main package of the module and of its
go.workmembers. - .NET: one launch per runnable, non-test project. When the project declares one literal
TargetFramework,programpoints atbin/Debug/<tfm>/<assembly>.dll, otherwise atbin/Debug/<assembly>.dll. Each entry is acoreclrlaunch withjustMyCode: true,stopAtEntry: falseand apreLaunchTasknaming the project’s build task (or the solution’s, when a solution covers the project). At launch, ifprogramdoes not exist, Glueprint looks for the same assembly in the target framework folders and uses the single match; with several, setprogramyourself, and with none, build the project first. - Java: one launch per main class under
src/main/java, without apreLaunchTask(the language server keeps the build current).
VS Code configurations
When a workspace has no .glueprint/launch.json, Glueprint uses .vscode/launch.json as it is, and
the Debug view labels the source:
- its
versionis not checked, andcompoundsandinputsare ignored; - entries that are not usable configurations are skipped, and a repeated name keeps the first;
- each
preLaunchTasklabel maps to the Run dock’s VS Code task of that label. The Run dock imports onlyshellandprocesstasks from.vscode/tasks.json, so a label that names an npm task or an automatic one such asnpm: buildis not found at launch; a label containing${is kept as written and fails.
Generating configurations in such a workspace creates .glueprint/launch.json and copies the VS
Code configurations into it first, once. From then on .glueprint/launch.json wins: configurations
you add to .vscode/launch.json later are not copied again.
Debug adapters
type in a configuration | Runtime | Debugger | The host also needs |
|---|---|---|---|
node, pwa-node | Node.js and TypeScript | js-debug | Node.js |
chrome, pwa-chrome, msedge, pwa-msedge | Chrome or Edge | js-debug | Node.js, and Chrome or Edge |
python, debugpy | Python | debugpy | Python 3.10 or newer for Glueprint’s debugpy |
go, delve | Go | Delve | Go |
coreclr, dotnet | .NET | netcoredbg | dotnet on PATH to launch a .dll (attach does not need it) |
java | Java | java-debug, inside the Java language server | a JDK 21 or newer |
For each launch Glueprint looks for the debugger in this order and takes the first it finds:
adapterPathin the configuration: an absolute path (a.jsfile runs undernode).- The debugger’s own key:
dlv,netcoredbg, or for debugpy thepythoninterpreter (which must be able toimport debugpy). PATH:js-debug-adapter,python3orpythonwith debugpy installed,dlv,netcoredbg.- For Delve:
$GOBIN, each$GOPATH’sbin, then~/go/bin. - The copy Glueprint installed.
Installing. When a debugger is missing, the Debug view says so (for example “Python (debugpy) isn’t installed”) with an Install button: Glueprint downloads a pinned build, checks its SHA-256, installs it into its own cache on the workspace’s host, and starts the launch again. Detect again checks again after you install something yourself, and Try again retries a launch whose runtime (Node.js, Python, a browser) was missing. The same list, with the same buttons, is in Settings > Editor & language > Debug adapters on the desktop (this computer only; install a remote host’s debuggers from its Debug tab) and in Settings > Editor > Debug adapters in the portal (pick the host as for Language servers). Java’s debugger comes with the Java language server: Install on either Java row, here or under Language servers, is one install of both.
Glueprint has builds of js-debug and debugpy for every platform, of Delve for macOS, Linux (x64 and
arm64) and Windows x64, and of netcoredbg for Apple Silicon Macs, Linux (x64 and arm64) and Windows
x64. Elsewhere the row says there is no build for the platform: install the debugger yourself
(go install github.com/go-delve/delve/cmd/dlv@latest builds Delve anywhere Go runs) and put it on
PATH or in adapterPath. If you download netcoredbg yourself, keep the extracted folder intact
(it needs the files next to the binary), and on macOS clear the quarantine attribute first with
xattr -dr com.apple.quarantine <folder>.
Python on macOS. Glueprint’s debugpy needs Python 3.10 or newer, and the python3 that ships
with Apple’s Command Line Tools is Python 3.9, so the Debug view asks for a newer Python. Install
one (for example from python.org or Homebrew), then click Try again in the Debug view.
TypeScript
A Node.js program written in TypeScript needs no build step. When a node launch’s program is a
.ts, .mts or .cts file and the configuration sets neither runtimeExecutable nor
runtimeArgs, Glueprint picks a runner on the host; the first match wins:
tsx, when it resolves from the launch’s working directory or a parent folder (--import tsx);ts-node(--require ts-node/register);- Node.js 22.18 or newer (or 23.6 and newer), which strips the types itself;
- Node.js 22.6 to 22.17 (or 23.0 to 23.5), with
--experimental-strip-types; - otherwise the launch fails with “Add tsx (npm i -D tsx) or use Node 22.18+.”
Every Node.js launch also gets sourceMaps: true, skipFiles: ["<node_internals>/**"] and
resolveSourceMapLocations: ["**", "!**/node_modules/**"] unless it sets them. A program that is
built into dist, build or out needs outFiles pointing at the built JavaScript (generated
configurations set it). A breakpoint in a .ts file stays hollow until the debugger binds it
through the source map; its tooltip says what it is waiting for.
Debug current file runs a .ts file from the workspace root, so a tsx installed only in one
package of a monorepo is not found: install tsx at the root, or write a launch configuration with
that package as its cwd.
Tests. Generate launch configurations adds “current file” configurations for Vitest and Jest
packages. With a *.test.* or *.spec.* file open, Debug this test runs it with the
configuration that covers it (the deepest package wins); these configurations need a file open in
the editor. Without a covering configuration, a test with a Node-compatible extension (.js,
.mjs, .cjs, .ts, .mts, .cts) runs with plain Node.js, with a note suggesting Generate
launch configurations. JSX/TSX tests require a covering Vitest or Jest configuration; otherwise
Debug current file refuses with <name> is a test file: generate launch configurations to debug it with Vitest or Jest.
(where <name> is the file name).
Browser debugging
js-debug also debugs front-end code in Google Chrome or Microsoft Edge (chrome and msedge
configurations). The browser opens on the workspace’s host, not in your own browser: for a
workspace on another host, it opens there.
- Debug in browser in the Debug tab and in the launch picker lists the dev servers this worktree
is serving, from the host’s port inventory (ports you hid there stay
hidden). Each entry opens
http://localhost:<port>withwebRootat the server’s folder, in Chrome, or in Edge when the host has no Chrome. - A
launchconfiguration takesurlandwebRoot. Anattachconnects to a browser started with--remote-debugging-port, onport(9222 when you leave it out). - Glueprint finds the browser where js-debug does:
CHROME_PATHorEDGE_PATH, then the standard install locations of the stable, Beta, Dev and Canary builds.runtimeExecutablenames a specific browser. - On Linux a launched browser needs a display. On a host without one, such as a server running the
CLI daemon, add
"runtimeArgs": ["--headless=new"]. - When the host has no usable browser, the launch stops with “JavaScript (js-debug) needs Google Chrome” (“needs Microsoft Edge” for an Edge configuration) and says how to fix it, and the js-debug row under Debug adapters in Settings reads “Chrome or Edge not found”.
- The Glueprint desktop app’s own window cannot be debugged this way.
Java
Java debugging runs inside the Java language server: Glueprint asks jdtls to start its
java-debug plugin and connects to the port it opens, so there is nothing to install beyond a JDK
21 or newer and Glueprint’s Java install, which fetches both jdtls and the plugin (see Debug
adapters above).
A launch configuration can be as small as { "type": "java", "request": "launch", "name": "App" }:
Glueprint asks the language server for the project’s main class and its classpath. Set mainClass
yourself when the project has several (the error names them), and projectName for a specific
Gradle subproject or Maven module. args, vmArgs, env and cwd work as in VS Code. The
language server keeps the project compiled, so no preLaunchTask is needed.
To attach, start the JVM with
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 and use
{ "type": "java", "request": "attach", "name": "Attach", "hostName": "localhost", "port": 5005 }.
The first launch after opening a project waits for the language server to finish importing the build (the Debug view says so); later launches start at once.
Breakpoints
Click the gutter left of a line number to add a breakpoint; hover the gutter to see where one would
go (“Click to add a breakpoint”, with the key). F9 toggles a breakpoint on the cursor’s line.
Right-click the gutter or a line number for the breakpoint menu: Add Breakpoint, Add
Conditional Breakpoint…, Add Logpoint…, Edit Breakpoint…, Disable or Enable
Breakpoint, and Remove Breakpoint. Right-clicking the text keeps the editor’s own menu.
- A condition pauses only when its expression is true, a hit count pauses on the hits it names (the debugger defines the syntax), and a logpoint prints its message to the Console instead of pausing. In the popover, Enter saves and Esc cancels; clearing every field leaves a plain breakpoint.
- The menu offers what the running sessions’ debuggers support; with no session it offers every kind. A kind a debugger turns out not to support shows as an unverified breakpoint that never pauses.
- A solid red dot is a breakpoint. A hollow ring means every running session that has the file reports it unverified; hover it for the debugger’s reason. Disabled breakpoints are grey, and conditional breakpoints and logpoints have their own markers.
- Breakpoints are saved per host and file and come back after a restart, up to 200 files of 100 breakpoints each (the file changed longest ago goes first).
- The Breakpoints view lists them by file, with a checkbox to enable each one, Remove, Remove all for the workspace, and a click to open the line.
Exception breakpoints. The Breakpoints view also shows the exception filters the session’s
debugger offers, such as caught and uncaught exceptions. Your choice is saved per configuration
type. The first time a type runs, Glueprint keeps the debugger’s default filters as soon as it
reports them, and sends them right away and at every later start; an exception thrown before that
first report follows the debugger’s own default.
While paused
- Variables shows the selected frame’s scopes; expand objects to drill in. Watch evaluates the expressions you add (they are saved). Call Stack lists the threads and frames; click a frame to open its source and see its variables. Console shows the program’s output and evaluates expressions in the selected frame.
- Hover a variable or a member chain such as
user.address.cityin the editor to see its value. Hovers work only while paused, including on Windows hosts, and never call a function or index into a value. Hovers send nothing while the host cannot be reached or no longer offers debugging. - Ask agent in the paused banner opens the send menu: pick a session of the workspace, or start a new one, and Glueprint fills its composer with where the program stopped: the stop reason, the top 8 frames, up to 20 of the selected frame’s local variables, three source lines before and after the paused line, and the last 5 lines of error output, about 6 KB at most. It only fills in the message: read it before you send it, because it contains your variables’ values. Starting a new session from the IDE pane closes the IDE sheet.
Agent tools
An agent in a session on this machine can help you debug through the built-in MCP server. It works only in its own worktree: it sees the debug sessions whose workspace root is inside it, and it can name only files inside it.
gp_editor_openshows a file at a line in the editor.gp_debug_configurationslists this worktree’s launch configurations.gp_debug_set_breakpointssets or clears breakpoints. You approve each call, and the breakpoints appear in the gutter like your own.gp_debug_sessions,gp_debug_stack,gp_debug_variablesandgp_debug_outputread a running session: where it is paused, the call stack, variables and recent output.
Starting and stopping sessions stays with you: pick the configuration and press Start. See the built-in MCP server.
Remote hosts
In the desktop app, a workspace on another host of your organization is debugged on that host: the debugger, your program and any browser run there, and breakpoints use that host’s paths. Hosts running the CLI daemon work the same way. The portal debugs every host like this (see Web portal below).
- The host must run a Glueprint version with the debugger (1.12 or later). An older host shows
Update Glueprint on <host> to debug here.in the Debug tab, the IDE pane and forF5, and its gutter offers no breakpoints. - While Glueprint cannot reach the host, its sessions stay readable but their controls are
disabled, the gutter is dimmed and its menu is read-only, and the Debug view says
Cannot reach <host> right now. Debugging resumes when it is back online.Changes you make in the Breakpoints view meanwhile are kept. When the host is back, the breakpoints you sent, and those changes, are sent again; a session that ended meanwhile readsSession ended while <host> was offline. - After a reconnect (the relay restarting, the computer waking from sleep, a network change), a
host that ran the debugger shows the same
Cannot reach <host>message until the host list confirms it, normally within a second. Otherwise, retry delays are 2 seconds, 8 seconds, then every 30 seconds until the host is confirmed; debugging then resumes by itself. A host shows the update message only once the confirmed list says it lacks the debugger. The desktop and the portal behave the same. - A start that times out is cancelled on the host. Stopping a session while it starts is not an error.
- A remote launch’s
cwdmust stay inside the workspace, and breakpoints in files outside the workspace are not set (they show as unverified). - Install a remote host’s debuggers from its Debug tab; desktop Settings lists this computer only.
- Sessions started from another computer do not appear in the host’s own app. Anyone in your organization who can see the host can watch, step and stop its sessions: a session someone else started appears while one of that host’s workspaces is on screen, but the editor never jumps to its pauses (open it with Show in the Debug chip). Watching it never changes its breakpoints, but your edits to a file reach every session you watch on that host. A session you start keeps streaming to you until it ends, even while no Debug view shows it.
- Two windows, or two portal tabs, following the same host can interrupt each other’s stream for up to 30 seconds.
- A reply too large to send (more than about 768 KB, for example a very large variable) fails with a message saying so instead of arriving cut short.
- Debugging another host uses the cloud relay. The desktop app needs Lite or above. The portal needs Pro or above. Debugging on this computer works on every plan, with or without an account.
Web portal
On Pro and above, the portal has the same debugger for every host of your organization that can run it; lower plans have no portal debugger. Breakpoints, watch expressions and exception choices are saved in this browser: its tabs share them, and they stay after you sign out.
- The Debug tab is in the workspace’s Run dock, inline or in the drawer on narrow screens, with the same update and offline messages as the desktop. Read-only docks have no Debug tab.
- The IDE sheet has the Debug pane under Files and Search. On a sheet 640 px wide or narrower, the column (Files or Search above Debug) covers the editor. The pane opens by itself only for a session this browser tab started, when it starts or pauses.
- The editor gutter works as on the desktop: the add hint, a click to toggle, the breakpoint menu on a gutter or line-number right-click (a text right-click keeps the editor’s own menu), the popover, and debug hovers while paused. Markers are dimmed and locked while the host cannot be reached, and absent for a host that needs an update.
- The floating toolbar sits at the top of the page, under every drawer, overlay and dialog, with a copy at the top of the IDE sheet. The status bar chip’s Show goes to the workspace. While a host is reconnecting, both keep showing its sessions with their controls disabled.
- The editor jumps to the paused line only in the workspace on screen; anywhere else the chip and the toolbar show the pause, and their location takes you there. Typing in a composer or a terminal is never interrupted, and a session this tab did not start (another tab, a teammate, the desktop) is shown in the chip and the toolbar but never jumped to.
- Settings > Editor > Debug adapters follows the Language servers host picker. A host that
needs an update shows the update message. A host that cannot be reached (also right after a
reconnect, until the host list confirms it) shows “Host unreachable” with
Cannot reach <host> right now. Its debug adapters show here once it is back online.instead of rows, which load by themselves once it is back. Install progress and failures are announced, and the one Java install shows on both Java rows. - Debug in browser opens the browser on the host, never in your browser.
- The keys differ, because a browser reloads on
F5and goes full screen onF11(see Keyboard shortcuts below).
Keyboard shortcuts
| Action | Desktop | Web portal |
|---|---|---|
| Start or continue | F5 | F8 |
| Stop | Shift+F5 | Shift+F8 |
| Restart | Cmd/Ctrl+Shift+F5 | Cmd/Ctrl+Shift+F8 |
| Toggle breakpoint | F9 | F9 |
| Step over | F10 | F10 |
| Step in | F11 | Alt+F10 |
| Step out | Shift+F11 | Alt+Shift+F10 |
| Show Debug View | Command palette | Command palette |
- Start or continue works anywhere in the workspace outside a text field or a terminal. Stop, Restart and the step keys need an editor or a Debug view, where they act on the session that view shows; from an editor they act on the active session. Toggle breakpoint needs an editor and toggles the cursor’s line of the editor that has focus, with the same host checks as the gutter. On both clients, a Debug view’s Watch and Console fields keep their typing keys, including in the IDE sheet: a shortcut rebound to a plain letter or editing key types there. Function keys and modified shortcuts still reach the debugger.
- In the portal the keys work inside the IDE sheet and the file peek’s source editor, but not
behind either or any other dialog.
F8andShift+F8win over the editor’s Go to Next / Previous Problem in Files there (Alt+F8still moves between the problems in one file). The browser reservesF5,F6,Shift+F5,Cmd/Ctrl+F5andF11; they cannot be assigned to a command. - In the portal,
F8on a paused session whose host cannot be reached showsCannot reach <host> right now. Debugging resumes when it is back online.and sends nothing. - A customized shortcut for another command on a Debug key applies only where that command can run; elsewhere the key keeps its Debug meaning.
- On GNOME,
Alt+F10maximizes the window: rebind Step In in Settings > Keyboard. - On a Mac keyboard the function keys control brightness and media unless you hold
Fnor turn on “Use F1, F2, etc. keys as standard function keys” in System Settings. - Rebind or remove any of them in Settings > Keyboard; see Keyboard shortcuts.
Limits
- Modern .NET only. Glueprint debugs SDK-style C# and F# projects on .NET 6+ / CoreCLR with
netcoredbg. It does not support .NET Framework, Mono, Unity or non-SDK-style projects, VB project
types, C++/CLI (
.vcxproj), Razor or Blazor language intelligence, XAML tooling, or Windows ARM64. - js-debug does not verify a breakpoint set through a symlinked path (for example macOS
/tmp, which is/private/tmp): it shows hollow, but it still pauses. - Breakpoints keep their line numbers while you edit: move them yourself after inserting or deleting lines above them. When the host replaces a clean file’s whole contents, the gutter redraws the breakpoints and paused line at their saved lines; ordinary typing does not move the saved lines.
- The mobile app has no debugger.