CalcSnippets Search
Tooling 3 min read

VS Code `launch.json` for Node Debugging Is Worth Learning Before You Blame the Runtime

A practical VS Code Node debugging guide that explains launch.json, when to use launch versus attach, and why a small debug config can save more time than another round of console.log guessing.

Why this matters more than people admit: many developers rely on console logging far past the point where a real debugger would be faster. Then when a bug becomes stateful or timing-sensitive, they realize they never really learned the debug configuration they have been skipping.

What launch.json is doing

In VS Code, launch.json defines how the debugger should run or attach to your application. For Node projects, that usually means one of two models:

  1. start the process under the debugger
  2. attach to an already-running process

Both are useful, and choosing the wrong one is a common source of confusion.

A basic Node launch config

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Run current file",
      "program": "${file}"
    }
  ]
}

This is enough to understand the model. VS Code launches Node itself, attaches the debugger immediately, and lets breakpoints work from process start.

Why launch is useful

Use launch when:

  • you want a repeatable debug entrypoint
  • the bug happens very early
  • the app is simple enough for the editor to start directly

That is why it is a strong default for small scripts, APIs, and many single-service Node apps.

When attach is better

Sometimes the process is already running in another way. Maybe a framework script, a custom startup flow, or a containerized environment is controlling how the app begins.

In that case, attach is often cleaner because you are telling VS Code to connect to an existing debug-enabled process instead of trying to recreate the startup logic inside the editor.

The practical lesson is that debugger confusion often comes from mixing up “how the app starts” with “how I want to inspect it.”

Why people think breakpoints are broken

Usually one of these is true:

  1. the wrong request type is being used
  2. the program path is wrong
  3. source maps or build output are not aligned
  4. the process was not launched in a debuggable way

That fourth point matters especially in TypeScript or framework-heavy projects. The editor cannot attach to debug state that the runtime never exposed.

A healthier debugging habit

Before changing runtime flags or blaming Node, ask:

  1. do I actually need launch or attach
  2. is the editor starting the right file
  3. is my built code the code I think I am debugging
  4. am I avoiding the debugger because I never configured it once properly

That last question is more common than people like to admit.

A practical TypeScript caution

Many Node projects are not running source files directly. They are running built output, a framework wrapper, or a transpiled path. That is why debugging feels “off” even when the config looks reasonable. The breakpoint problem may not be the debugger at all. It may be that the runtime path and the source path stopped matching in your head.

This is exactly why it helps to keep the first debug configuration extremely honest and minimal before adding more abstraction.

Final recommendation

If you work in Node regularly, learning one good launch.json setup is worth the time. It turns the debugger from a vague optional feature into part of normal development. Most developers do not need a giant debug taxonomy. They need one clean config they trust and the judgment to know when launching and attaching are different problems.

Sources

Keep reading

Related guides