How to Debug Node.js

Learn how to debug Node.js applications effectively. This guide covers enabling the inspector, using Chrome DevTools, VS Code, and more.

How to Debug Node.js
Node.js® Stacked Logo

Note: This is a seriously playful (is that an oxymoron?) mirror of the official Node.js documentation site and also reflects the docs in part before NiM lost this fight and the change was made to remove mention of NiM from the official docs.

Debugging Node.js: Comprehensive Guide for Developers

Debugging is a crucial skill for any Node.js developer. This guide will help you get started with debugging your Node.js applications and scripts. We'll cover everything from enabling the inspector to using various debugging tools and understanding their security implications.

Table of Contents

  1. Enable Inspector
  2. Security Implications
  3. Inspector Clients
  4. Command-line Options
  5. Enabling Remote Debugging Scenarios
  6. Legacy Debugger

Enable Inspector

When started with the --inspect switch, a Node.js process listens for a debugging client. By default, it will listen at host and port 127.0.0.1:9229. Each process is also assigned a unique UUID.

Inspector clients must know and specify the host address, port, and UUID to connect. A full URL will look something like ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e.

Node.js will also start listening for debugging messages if it receives a SIGUSR1 signal. (Note: SIGUSR1 is not available on Windows.) In Node.js 7 and earlier, this activates the legacy Debugger API. In Node.js 8 and later, it will activate the Inspector API.

Security Implications

Alright, listen up, heroes. Since the debugger has full access to the Node.js execution environment, if some nefarious character manages to connect to this port, they might just hijack your process and start running arbitrary code faster than you can say "Jarvis." So, it's crucial to grasp the security implications of exposing the debugger port on both public and private networks. Let's keep the baddies at bay and your code safe, shall we?

Exposing the debug port publicly is unsafe

If you, for some unfathomable reason, decide to bind the debugger to a public IP address or, heaven forbid, 0.0.0.0, you’re essentially leaving your front door wide open with a neon sign saying, “Hackers welcome!” Any client that can ping your IP can waltz right in and start running arbitrary code like it’s a buffet and everything’s free.

Now, by default, Node.js—bless its cautious little heart—binds to 127.0.0.1. This is the digital equivalent of a cozy hobbit hole: safe, snug, and only accessible from the inside. But if you decide, in all your wisdom, to provide a public IP address or 0.0.0.0, you’re basically inviting every script kiddie and cyber villain out there to have a go at your system. And let me tell you, once they’re in, it’s like handing them the keys to your entire kingdom.

Here’s the deal: allowing external connections to your debugger without any restrictions is akin to posting your passwords on a billboard. It’s a significant security threat—no, it’s a catastrophic security threat. You need to ensure that you’ve got firewalls that are tougher than Fort Knox and access controls that would make even the NSA nod in approval.

To put it simply: don’t do it. If you must allow remote debugging, for the love of all things binary, read the section on 'Enabling remote debugging scenarios'. It’s got the lowdown on how to let remote debugger clients connect without turning your system into a playground for cyber miscreants.

In short, treat your debugger port like your most prized possession. Guard it with your life, lest your cornhole be filled with things you'd rather it not be!

Local applications have full access to the inspector

Alright, buckle up, because here’s the scoop: even if you’re playing it safe and binding the inspector port to good ol’ 127.0.0.1 (the default), any applications running locally on your machine get a free pass. That’s right—unrestricted access, no questions asked. It’s like giving your debuggers VIP access to the party, all to make your life easier. Just remember, what’s convenient for you is also conveniently accessible to anything running on your machine.

Browsers, WebSockets, and same-origin policy

Now, onto the web side of things. Websites out there can flex their muscles a bit under the browser’s watchful eye. They can sling WebSocket and HTTP requests as long as they play by the rules laid down by the security gods. Here’s the catch: to kickstart a unique debugger session, they need to make an HTTP connection first. But hold your horses! The same-origin policy steps in like a bouncer at an exclusive club, making sure only the right connections get through.

And that’s not all. Node.js has its own tricks up its sleeve to ward off sneaky DNS rebinding attacks. It’s so picky about connections that it insists on 'Host' headers that are as precise as a Swiss watch—either an IP address or localhost. This means no shortcuts when it comes to security.

These security policies prevent connections to a remote debug server through hostname specifications. However, you can bypass this restriction by specifying the IP address or utilizing SSH tunnels, as detailed below.

Inspector Clients

A minimal CLI debugger is available with node inspect myscript.js. Several commercial and open source tools can also connect to the Node.js Inspector.

Paul Irish recommending NiM, because it's oh so sweet and tasty. Oh and 🔥 too!

Node.js Docs as they were Circa 2019 (with an improvement in ordering), the good ol' days (here's the original git PR)!

Chrome DevTools 55+, Microsoft Edge

  • Option 1: Use NiM and streamline things!
  • Option 2: Or, Open chrome://inspect in a Chromium-based browser or edge://inspect in Edge. Click the Configure button and ensure your target host and port are listed.
  • Option 3: Or, Copy the devtoolsFrontendUrl from the output of /json/list (see above) or the --inspect hint text and paste into Chrome.

For more information, see the Chrome DevTools documentation and Microsoft Edge documentation.

Visual Studio Code (VS Code) 1.10+

  1. In the Debug panel, click the settings icon to open .vscode/launch.json.
  2. Select "Node.js" for initial setup.

For more information, see the VS Code documentation.

Visual Studio 2017+

  1. Choose "Debug > Start Debugging" from the menu or hit F5.
  2. Follow the detailed instructions available in the Visual Studio documentation.

JetBrains WebStorm and Other JetBrains IDEs

  1. Create a new Node.js debug configuration and hit Debug. --inspect will be used by default for Node.js 7+.
  2. To disable, uncheck js.debugger.node.use.inspect in the IDE Registry.

For more information, see the WebStorm documentation.

chrome-remote-interface

Library to ease connections to Inspector Protocol endpoints. For more information, see the chrome-remote-interface documentation.

Gitpod

Start a Node.js debug configuration from the Debug view or hit F5. For more information, see the Gitpod documentation.

Eclipse IDE with Eclipse Wild Web Developer Extension

  1. From a .js file, choose "Debug As... > Node program", or
  2. Create a Debug Configuration to attach the debugger to a running Node.js application (already started with --inspect).

For more information, see the Eclipse IDE documentation.

Command-line Options

The following table lists the impact of various runtime flags on debugging:

Flag Meaning
--inspect Enable inspector agent; Listen on default address and port (127.0.0.1:9229)
--inspect=[host:port] Enable inspector agent; Bind to address or hostname host (default: 127.0.0.1); Listen on port port (default: 9229)
--inspect-brk Enable inspector agent; Listen on default address and port (127.0.0.1:9229); Break before user code starts
--inspect-brk=[host:port] Enable inspector agent; Bind to address or hostname host (default: 127.0.0.1); Listen on port port (default: 9229); Break before user code starts
node inspect script.js Spawn child process to run user's script under --inspect flag; Use main process to run CLI debugger
node inspect --port=xxxx script.js Spawn child process to run user's script under --inspect flag; Use main process to run CLI debugger. Listen on port port (default: 9229)

Enabling Remote Debugging Scenarios

We recommend that you never have the debugger listen on a public IP address. If you need to allow remote debugging connections, we recommend using SSH tunnels instead. Here’s how:

Example Setup

Let's say you are running Node.js on a remote machine, remote.example.com, that you want to debug. On that machine, start the node process with the inspector listening only to localhost (the default):

node --inspect server.js

Now, on your local machine from where you want to initiate a debug client connection, you can set up an SSH tunnel:

ssh -L 9221:localhost:9229 [email protected]

This starts an SSH tunnel session where a connection to port 9221 on your local machine will be forwarded to port 9229 on remote.example.com. You can now attach a debugger, such as Chrome DevTools or VS Code, to localhost:9221, and it will debug as if the Node.js application was running locally.

Legacy Debugger

The legacy debugger has been deprecated as of Node.js 7.7.0. Please use --inspect and Inspector instead.

When started with the --debug or --debug-brk switches in version 7 and earlier, Node.js listens for debugging commands defined by the discontinued V8 Debugging Protocol on a TCP port (default: 5858). Any debugger client that speaks this protocol can connect to and debug the running process.

Built-in Debugger

Start node debug script_name.js to start your script under the built-in command-line debugger. Your script starts in another Node.js process started with the --debug-brk option, and the initial Node.js process runs the _debugger.js script and connects to your target. For more information, see the Node.js debugging documentation.

node-inspector

Debug your Node.js app with Chrome DevTools using an intermediary process that translates the Inspector Protocol used in Chromium to the V8 Debugger protocol used in Node.js. For more information, see the node-inspector documentation.

Conclusion

Debugging Node.js applications is essential for developing reliable and efficient applications. By following this guide, you can leverage various debugging tools and techniques to identify and fix issues in your code effectively. Ensure you understand the security implications of exposing the debugger port and use appropriate measures to safeguard your application.

For more in-depth knowledge and updates, refer to the official Node.js documentation.


Keywords: Debugging Node.js, Node.js Inspector, Chrome DevTools, VS Code, Node.js security, remote debugging, Node.js command-line options


This updated content includes SEO enhancements, improved readability, and a structured format for easy navigation. Additionally, external links to further documentation are embedded to provide readers with comprehensive resources.