Debugger
VS Code’s debugger uses launch.json in .vscode/. Each “configuration” defines how to launch / attach. Set breakpoints, inspect variables, evaluate expressions, step through — everything you’d expect from an IDE.
Node / Python / browser configs
EXAMPLE
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Node — current file",
"type": "node",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"skipFiles":["<node_internals>/**"]
},
{
"name": "Node — npm script (dev)",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"console": "integratedTerminal",
"skipFiles":["<node_internals>/**"]
},
{
"name": "Node — attach to running process",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true,
"skipFiles":["<node_internals>/**"]
// Start your app with: node --inspect=0.0.0.0:9229 server.js
},
{
"name": "Vitest — current test file",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/vitest",
"args": ["run", "${relativeFile}"],
"console": "integratedTerminal"
},
{
"name": "Python — current file",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": false
},
{
"name": "Python — Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver", "--noreload"],
"django": true
},
{
"name": "Chrome — Vite dev server",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}"
}
]
}
// .vscode/tasks.json — combine build + launch
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "npm run build"
}
]
}
// Launch with `preLaunchTask: "build"` to compile first.
# Debugging features to actually use
# - Conditional breakpoints — right-click a breakpoint → Edit → expression
# e.g. user.id === 'u_42'
# - Logpoints — print to debug console without modifying code
# e.g. `value = {value}` (right-click → Add Logpoint)
# - Watch — track expressions: `users.length`, `state.cart.total`
# - Call stack — click frames to inspect that scope
# - Debug console — type any JS expression in the current scope
# - Step Over / Into / Out / Continue — F10 / F11 / Shift+F11 / F5
# - Hot-reload + debug — keep the same debug session attached across nodemon restarts
# (use `"restart": true` on attach configs)
# Debugging containers
# - Add a launch config with `type: "node"`, `request: "attach"`, `address: "localhost"`,
# `port: 9229`, then `docker run -p 9229:9229 ...` your image with --inspect
# - VS Code's `Dev Containers` extension can launch your dev container itself
# Source maps — required for transpiled languages
# - TypeScript: tsconfig.json → sourceMap: true
# - Vite / webpack: enabled by default in dev
# - Production: ship source maps separately, gate by IP/auth to keep them private
# Tips
# • Pin a breakpoint to a specific commit with `// @ts-ignore` markers if needed
# • Use the Debug toolbar to switch configs without leaving the file
# • F5 is muscle memory — set it as Start Debugging in your keybindings
Why it matters
A working launch.json for “npm run dev” pays for itself in the first week. Logpoints replace 90% of console.log — no PR noise, no forgotten debug lines.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{ "type": "node", "request": "launch", "name": "Debug", "program": "${workspaceFolder}/index.js" }
]
}
// F5 starts. F9 toggles a breakpoint.
Try it Yourself »
Exercise
Default key to start the debugger.
Function key.
Discussion
Loading…