Node.js can expose a running process to a debugger through the V8 Inspector protocol. Use the inspector when a runtime bug needs breakpoints, startup tracing, or variable inspection instead of only log output.
The inspector listener is a local TCP endpoint, and Node.js listens on 127.0.0.1:9229 by default. Keeping the listener on loopback lets local debugger clients attach without opening the debug port to other machines.
The built-in node inspect client keeps the attach path reproducible from a terminal. Chrome DevTools, Edge DevTools, Visual Studio Code, and other inspector clients can attach to the same host and port after the process is started with the inspector enabled.
Related: How to debug a Node.js memory leak
Related: How to use the Node.js REPL
Steps to debug a Node.js process with the inspector:
- Keep the inspector address on loopback unless remote access is protected by a tunnel or firewall.
Do not bind the inspector to 0.0.0.0 on an untrusted network. A client that reaches the inspector can run code inside the Node.js process.
- Start the target script with the inspector paused before user code.
$ node --inspect-brk=127.0.0.1:9229 server.mjs Debugger listening on ws://127.0.0.1:9229/4d8a7b3e-9b22-4b2d-9f3d-6c41d2a8e717 For help, see: https://nodejs.org/learn/getting-started/debugging
Replace server.mjs with the application entry point. Use --inspect instead of --inspect-brk when the process should start immediately instead of stopping before user code.
- Attach the built-in CLI debugger from a second terminal.
$ node inspect 127.0.0.1:9229 connecting to 127.0.0.1:9229 ... ok debug> Break on start in server.mjs:1 > 1 import http from "node:http"; 2 3 const server = http.createServer((request, response) => { debug> - Continue the paused process from the debugger prompt.
debug> cont
The node inspect prompt also accepts debugger commands such as next, step, out, and repl after execution reaches code that needs inspection.
- Confirm the application still answers after continuing from the debugger.
$ curl --silent http://127.0.0.1:3000/ debug-ready
Use the application's normal smoke test when the process is not an HTTP server or listens on a different local port.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.