Top 10 Node.js Debugging Tips You Probably Didn't Know

Top 10 Node.js Debugging Tips You Probably Didn't Know

In this blog, we are going to see how to debug a node.js app. Previously, in node.js, debugging could be done using the debug command.


In this blog, we are going to see how to debug a node.js app. Previously, in node.js, debugging could be done using the debug command.

Today we’re going beyond just logging everywhere in your application. Many resources on Node.js debugging go through only one single method, but in this article, we’re going to cover ten unique tools you can use to debug your Node.js application like a pro.

1: Test

Testing shouldn’t be controversial. Yet spending the past few years as a consultant developer, I’ve now seen so many teams hand-wave at test-driven development and opt instead to put themselves into a world of pain. The tests you skip writing today will short-change your future developers’ debugging abilities.

Tests are so useful during debugging because you can use them as documentation of your code’s behavior and APIs. When you’re rifling through code searching for a bug and stop to ask yourself, “Hold up, why are they using a .forEach, not a .map?” it is immeasurably helpful to see the creator’s thoughts encapsulated in test case descriptions and example code.

If you want to get up and running with tests, I can highly recommend Jest as a unit testing library. Not only is Jest super fast, but it comes with lots of goodies as well, such as the ability to create coverage reports by passing a coverage flag to your testing reports. But one of my absolute favorite features for Jest is how you can mock required dependencies simply.

If you’re building APIs, SuperTest is a great testing library for API endpoints. SuperTest is particularly cool because you can pass it an Express app object directly. This means you don’t have to have the app running separately, and it makes mocking dependencies such as database connections easy.

But wait, there’s more!

Combine your Jest unit tests with your SuperTest ones with Husky (a Git hook utility) pre-commit hook](, and you can run all your unit and integration tests before your code even leaves your machine. I absolutely love this.

2: Check out Postman

The debugging tools we’ve talked through so far will only work if you’re also executing your software as your users would. A common use case for Node.js is to build RESTful APIs. If you’re building APIs and you’re not familiar with Postman, you’re in for a treat.

Postman is a small application that allows you to set up, save, and run API commands. While running commands such as GET can be easily simulated by navigating through the browser, POST requests aren’t as straightforward. In Postman, you can set up the API requests you want, and fire them off at the click of a button.

Postman has gotten quite advanced recently, adding ability to do things like pre- and post-scripting. These scripts allow you to dynamically update your requests before they’re sent (for instance, updating a timestamp), or save values from your response to use in subsequent requests. Simply put: you can run a list of chained commands, and pass through the returned values. So if you’re making advanced RESTful APIs with Node.js, Postman is your holy grail.

3: Explore alternative console methods

Ah, the humble console.log.

Most JavaScript developers are familiar with the console log. If you’re not, it simply takes a string or an object and prints it. But what most developers don’t know is that the console object itself has many more useful methods that are often left underutilized. Let me show you a couple of my favorites.

By running, you create a new collection of JavaScript console logs. In the browser, this would nest all your logs together. However in Node.js, since you only have the console to log to, each group is indented like so:

I am a console log indented by a single level
    I am a multilevel nested console log


Next up is console.table. Console.table does what you’d expect it to: it takes an array or an object and outputs an ASCII table. This is particularly useful for long or large objects with many properties, as it gives us more structure which can help with readability, like so:

│ (index) │ Values │
│    0    │    1   │
│    1    │    2   │
│    2    │    3   │


Last up, console.dir.

The reason I’m giving this a shoutout is because it takes two arguments, the last of which is the important one.

The first takes an object; the second takes an object of options. In this options object, you can specify the depth of your console log. If you have ever tried to console log a native Node.js object and gotten a HUGE output, you’ll know how hard it is to read.

But instead, with console.dir and a depth property, you get the following:

process {
    title: 'node',
    version: 'v10.8.0',
    versions: [Object]

Instead of showing all the child properties (note the versions property) you get:

process {
    title: 'node',
    version: 'v10.8.0',
    versions: {
        http_parser: '2.8.0',
        node: '10.8.0',
        v8: '',

Play around with console

If you’re keen to play with the different methods, simply copy the following code file:

// Example 1: console.log
// ======================
console.log('I am a regular console log.');;
console.log('I am a console log indented by a single level');;
console.log('I am a multilevel nested console log');

// Example 2: console.table
// ========================
const people = [["John", "Smith"], ["Jane", "Doe"], ["Emily", "Jones"]]

// Example 3: console.dir
// ======================
const object = {
    name: "Lou",
    likes: ['JavaScript', 'Node.js']
console.dir(process, {colors: true, depth: 0 })

Save the file as app.js and run with the command:

node app.js

Now you’ll see the output of all the three different console commands, and you can experiment with them to get a better feel for how they change the debugging experience. Rather than just having plain console logs, now you’ll have structured entries, that should be easier to make sense of, and more suited to the debugging style that you’re performing.

4: Experiment with the humble debugger

Okay, now that you’re a master of the console log, it’s time to take it up a notch.

Enter: the debugger statement.

For those coming straight to Node.js who haven’t developed in the browser, the debugger statement is one of the simplest ways to get started with debugging. In the browser, a debugger statement simply pauses the execution of your code when the statement is reached…but only if you have the developer tools open.

If you want to quickly try this out, open up your dev tools and paste the following into the console.

(() => debugger;)()

You’ll see the browser stops executing on this line, which allows you to see all the scoped variables at this point in time and experiment with executing code.

In Node.js, however, there is no developer console, which means that we have to do things a little differently. We have to do the equivalent of opening up the developer tools, but this time inside of Node.js. And we do that by using Node.js’ inspect.

For instance, take the following example app:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send('Hello World!');

app.listen(3000, () =>'Example app listening on port 3000!'));

Now instead of starting your app as you usually would:

node app.js

You can start your app with the following command:

node inspect app.js

And you’ll be dropped into an interactive debugger. In the command line, this allows you to step through code execution.

So I must admit, this is a very primitive method of debugging.

However, I intentionally wanted to show you all the different ways to debug in Node.js so that in the future if you come across this method, you know how it works. While this method works for small Node.js scripts and apps, for more serious debugging, you might need something more powerful.

So let’s take a look at what these methods are.

5: Debugging in Chrome with the inspect flag

For debugging Node.js apps, this is by far my favorite method.

When Node.js was created, it felt like we lost all of the debugging capabilities of the browser. But with the inspect flag, you get most (though not all) of these capabilities back.

The way this works is: you pass a flag to your node process before you start the Node application. This tells Node.js that you want to run in debugging mode. Node.js will then start a WebSocket connection that will allow you to remote debug from your browser.

node --inspect app.js

Hold up for one second; you want to be careful to not confuse the—inspect flag with the inspect command (from tip three). The former launches the CLI debugger, whereas the latter launches the browser-based debugger.

Now if you’re using Chrome, you can head over to the chrome://inspect#devices page and you’ll see a section called remote target. This will show all of your running node processes that you are using that have been executed with the inspect flag.

Click your app in the list and you’ll be sent into a debugging terminal in Chrome!

There’s not too much more we need to say about debugging with the inspect flag. If you’re trying to catch small-ish bugs, this is the best method.

But it’s not the only method.

6: Debug in your IDE (VS Code)

If you thought stepping through your code in your browser was cool, you might like this even more: some IDEs make use of the inspect flag and allow you to do remote debugging without even leaving your IDE.

These IDE tools work in much the same way as before. You’ll need to attach an inspector to your node process and then listen on the WebSocket that is created for your debugging purposes.

I’m a big fan of VS Code, and since it’s the most popular JS IDE, let me walk you through how to set up debugging in VS Code. Note that the same can be done in WebStorm, if that’s what you’re into.

To start, copy the following Express app (and save the file as app.js):

const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send('Hello World!');

app.listen(3000, () =>'Example app listening on port 3000!'));

Then, run your app with the following command:

node app.js

And you should see the output:

Example app listening on port 3000!

You may notice that (unlike before) we’re not passing the—inspect flag. There are two ways to set up your node process with inspect mode, either by passing the flag from within your IDE or through your IDE. So let’s explore the new approach, via your IDE.

Now that your app is running, go to VS Code and open the command palette, either with the view tab or by pressing:

Shift + Cmd + p

Select Attach to Node Process.

You should now have another menu (shown below) of the running node processes.

Select the top option to attach the debugger.

Now your running node process is accessible for debugging.

Your console should now show:

Debugger listening on ws://

Lastly, reopen the command palette and select the debug option.

Your console should now say:

Debugger attached.

And your IDE will show the active orange bottom bar.

And you’re up and debugging! You can add breakpoints to your code right in your IDE, plus see the scoping of variables and the call stack.

7: Hook up logging/APM tooling

As much fun as it is to intercept your container requests with inspect and step through your code, you won’t have this option in production. This is why it makes a lot of sense to try and debug your application locally in the same way as you would in production.

In production, one of your tools would be to login to your remote server to view the console logs, just as you would on local. But this can be a tedious approach. Luckily, there are tools out there that perform what is called log aggregation, such as Stackify.

These tools send your logs from your running application into a single location. They often come with high-powered search and query utilities so that you can easily parse your logs and visualize them.

In order to get your logs output, you may also want to use a logging library, such as Winston or Bunyan. These libraries help you format your logs and help with streaming them to your centralized log aggregator systems.

You can also apply logs with a log level. This is an environment-specific configuration that allows you to toggle how fine-grained your log entries are. This can help you to not drown in log entries. It’s not always beneficial to log absolutely everything.

Another tool for remote debugging Node.js is APM (Application Performance Monitoring). APM works by extracting your stack traces inside your code and sending them off to a central location for further analysis, such as with Stackify’s Retrace tooling.

If you’re serious about building Node.js applications, you’ll want to think about how you’re going to observe and monitor your system from the start, which will likely mean instrumenting your code with logs. The sooner you learn how you need to visualize your Node.js application, the better.

8: Test performance

When many think debugging, they think your typical stepping-through-the-debugger-type interactions. However, some issues only show their face during high load. In these cases, you’ll need some way to performance test

My favorite tool for performance testing Node.js is Artillery.

Artillery allows you to create a YAML configuration file that defines the type of performance tests you want to run. For instance, you might want to simulate how your system behaves during peak load, so you can define a profile that hits your application with low traffic before all of a sudden flooding it with requests.

By using tools like Artillery, you can get a much better picture of how your system behaves and help with your debugging.

9: Use flame graphing

In JavaScript, it’s helpful to understand how your functions are executed, and flame graphs are a great way to visualize how your function execution happens.

A flame graph models your call stack. When a function is executed, it might call another, and another, and another. Eventually at the end of this chain of functions, one will return, which will return to the subsequent function, which will return to the function that called it, and so on until the call stack becomes free again.

This is useful because you will want to see how your application is behaving with respect to your call stack. You might want to see how long functions are running or what other functions they are calling. This is something that simply can’t be done with console.log alone…but it can be done with a flame graph such as flamebearer.

10: Remember to debug memory leaks

Last up: debugging memory leaks.

A memory leak occurs when there is memory that is not properly freed up, which can lead to increasing amounts of memory being taken up by your application. If never attended to, this can lead to your application running out of memory and potentially crashing. It also means that you might need to provision bigger servers in order to run your leaky application—not good! In JavaScript, memory leaks can be created by (among other things) global variables, closures, or callback functions.

To debug memory leaks, repeat the inspect step from tip four to open up Chrome. Once it’s opened, you will see a memory tab. This allows you to profile your memory usage within your Node.js application and find those pesky leaks!

That’s a wrap!

That’s all we’ve got time for today. Hopefully, we’ve given you some good inspiration and some jumping off points to improve the way you’re debugging in your Node.js applications. Next time you find yourself pulling your hair out throwing console.log statements all over your code, just remember: there are better ways to debug!

So use them - Thank you for reading!

Node.js for Beginners - Learn Node.js from Scratch (Step by Step)

Node.js for Beginners - Learn Node.js from Scratch (Step by Step)

Node.js for Beginners - Learn Node.js from Scratch (Step by Step) - Learn the basics of Node.js. This Node.js tutorial will guide you step by step so that you will learn basics and theory of every part. Learn to use Node.js like a professional. You’ll learn: Basic Of Node, Modules, NPM In Node, Event, Email, Uploading File, Advance Of Node.

Node.js for Beginners

Learn Node.js from Scratch (Step by Step)

Welcome to my course "Node.js for Beginners - Learn Node.js from Scratch". This course will guide you step by step so that you will learn basics and theory of every part. This course contain hands on example so that you can understand coding in Node.js better. If you have no previous knowledge or experience in Node.js, you will like that the course begins with Node.js basics. otherwise if you have few experience in programming in Node.js, this course can help you learn some new information . This course contain hands on practical examples without neglecting theory and basics. Learn to use Node.js like a professional. This comprehensive course will allow to work on the real world as an expert!
What you’ll learn:

  • Basic Of Node
  • Modules
  • NPM In Node
  • Event
  • Email
  • Uploading File
  • Advance Of Node

The Ultimate Node.js Beginner Tutorial

The Ultimate Node.js Beginner Tutorial

This tutorial is for all developers who want to program with Node.js but don't know much about Node.js yet. Node.js is becoming more and more popular and every web developer should know at least the basics. After this tutorial you can clearly count yourself in this group.

This tutorial is for all developers who want to program with Node.js but don't know much about Node.js yet. Node.js is becoming more and more popular and every web developer should know at least the basics. After this tutorial you can clearly count yourself in this group.

So that you have a red thread through this Node.js Tutorial, I have you the points times summarized:

Table Of Contents 1. What is Node.js?

With Node.js the scripting language JavaScript has also found its way into server-side programming. Before Node.js JavaScript was mainly responsible for the frontend and the interaction with the visitor. With Node.js you can now develop from small CLI (Command Line) tools to complex programs and HTTP servers. Exactly this universal usability makes Node.js for me personally - and also for many other developers - so ingenious!

If you are wondering if you really need Node.js and want to be able to use it, you should read the most frequently asked questions below and decide if Node.js is the right technology for you.

Another important reason for the success are the on-board resources that come with Node.js. From the ground up, Node.js already has many features and modules that are easy to use. And to make the system even more perfect, there is the package manager - also called npm (Node Package Manager). More information can be found later in the Node.js Module section. Anyway, it's very easy to add new features, like extensions from other developers.

That sounds promising at first, but can you imagine anything concrete about it? Probably not. At least it wouldn't be very easy for me if I read something like this on a topic I didn't know. Therefore read this section best at the end of this article once again and I assure you, you will know what I am talking about! ;)

2. Install Node.js

Before we can start programming, we first have to install Node.js on our computer. Now select the operating system you want to develop on. Windows or Mac…?

2.1 Windows

Under Windows you can simply download the installer and follow the installation instructions. It is best to download the LTS (Long-term support) version as it is already established and has fewer bugs than the latest version.
Windows Installer

2.2 Mac

On a Mac, just like Windows, you can download the official installer and follow the installation instructions. Also download the LTS (Long-term support) version, because it is already established and has less bugs than the latest version.
Mac Installer

2.3 Plesk (Hosting)

If you manage your domains with Plesk and want to host your app there, all you need is the Node.js extension, which you can download with a simple click.

To develop, however, you should work locally on your Mac or Windows computer. When your app is ready and you want to deploy it, you can use this guide to help you.

3. CLI

CLI stands for Command-Line Interface and means command line. On the Mac you can use the pre-installed program "Terminal" and on Windows the command prompt (cmd.exe).

With this we can "control" Node.js. With the command node we can now execute any JavaScript command. In the further course of this article you will now know what you can understand by the CLI.

4. Node.js Modules

The crown jewels of Node.js are its modules. At the beginning I already mentioned that Node.js has a package manager. The abbreviation and the command for the CLI is npm (Node Package Manager).

NPM is a gigantic network of development tools that can be downloaded free of charge for your application. If you work with Node.js, you'll find that you have to rely on other developers' modules over and over again. You don't have to reinvent the wheel all the time.

In this example we download the express module:

npm install express

You can also install modules globally, which means it applies to your entire computer and is not only available in one project. Just append the parameter -g.

npm install -g express

When you install a module, the node_modules folder is automatically created. This folder contains all installed modules and can normally be ignored by you. We can include a module in the code later in this way:

const express = require('express');

5. First project

5.1 Create project

The time has come, we're finally starting programming. To create a Node.js project, we simply create a normal folder in any directory. There we create an index.js, which is our start file.

5.2 Initialize Node.js App

Now we have to say in this folder that we want to make a Node.js app out of it, we do that with this command:

npm init

We are asked for different parameters like package name, version and description. You can fill in these fields or just leave them at their default values. We can change these settings later at any time.

5.3 package.json

A package.json file has now been created in our folder. This file contains all information about the author, version and most importantly, about all installed dependencies (modules).

// package.json

  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "author": "",
  "license": "ISC"

5.4 Write program code

Now we can write the first JavaScript code in our index.js. Of course we can't do without it and have to spend "Hello World".

// index.js

console.log('Hello World');

5.5 Test application

The first code is written and we want to start our program. This is what we do with this command:

node index.js

We get this result, cool! 🥳

6. Automatic App Restarts (Nodemon)

It's really annoying when we have to manually restart our Node.js app after every little change to the code, isn't it? Right, so there is the module nodemon, which we install globally. This module detects file changes and restarts the Node.js app within milliseconds. This speeds up our workflow enormously.

npm install -g nodemon

After the installation we start Nodemon with this command and immediately our app is started and restarted automatically when changes are made.

nodemon index.js

If you now save your files within the project folder, the Node.js app will automatically restart.

7. Browser output

Now we already want to set up our first small web server in order to be able to deliver content in the browser. Therefore we install the module express with the following command:

npm install express

And we adjust our index.js like this:

// index.js

const express = require('express');
const app = express();

app.get('/', (request, response) => {
  response.send('Our first Node.js webserver');

app.listen(3000, () => console.log('Server running on port 3000'));

To help you understand everything, here is an explanation line by line:
Line 3: Integration of the express module.
Line 4: Initialization of the express module in the variable app.
Line 6: We intercept the page call from / to our server to perform an action.
Line 7: We send the text "Our first Node.js webserver" back to the requestor as an answer.
Line 9: We start our web server on port 3000 and display a message in the console.

If we ask for browser now our computer on the port 3000, we get this result:

Simple, isn't it? That's why Node.js is so brilliant. You only need seven lines of code for your own web server.

If we now adjust our route a little bit, we can return data that has already been transferred:

// index.js

const express = require('express');
const app = express();

app.get('/:yourName', (req, res) => {
  res.send('Your name: ' + req.params.yourName);

app.listen(3000, () => console.log('Server running on port 3000'));

Here :yourName stands for a variable string that we can pass in our URL and with req.params.yourName we can read it and send the name back to the user.

If we now call http://localhost:3000/test, we get the string with the given name as response. So you can already read and send data with really little code.

8. FAQ

When do I use Node.js?

Node.js is primarily used for "normal" dynamic websites and backend APIs (RestAPIs). In addition, Node.js is often used in applications that need to process data in real time (e.g. chats).

Is Node.js a programming language?

Definitely no. Node.js connects the scripting language JavaScript and a network component. Since Node.js was developed on the Google V8 JavaScript engine, Node.js masters the basics of network technology such as the HTTP, DNS and TCP protocols.

Is it easy to learn Node.js?

Since Node.js is not a framework and not a programming language, you have to ask yourself if it is easy to learn JavaScript. Surveys have shown that JavaScript is one of the easiest scripting languages to learn.

What is middleware?

A middleware is a part-program, i.e. a function that is executed between two components. For example, if the user calls /settings, the actual program code should only be executed if the user is logged on. To do this, you write a middleware function and call this function before. This is done so that the same code (checking the login) can be used several times, but only has to be written once.

How and where can I host a Node.js app?

For example, you can host Node.js Apps for free at Heroku.

What does the package.json do?

The package.json at Node.js Apps contains information about the name, the author, and much more. Most important are the dependencies. This is a list of the modules (dependencies) your app uses. You can also use scripts to define commands to run or test your app.

What does the node_modules folder do?

The node_modules folder contains all modules included in your node.js. This folder contains standard modules, but also all modules that you have additionally installed and that are listed in the package.json under scripts. You don't need to push the node_modules folder into your git repository or live hosting, because the npm install command will download all modules into the folder again.


Pooh! Quite a lot of information at once, isn't it? Nevertheless I hope that you got a good impression of what is possible with Node.js and I made you curious for more. If so, you are welcome to continue looking around on and read even more exciting articles about web development. You are welcome to write any unsettled questions in the comments! :)

Node.js Tutorial | Learn Node.js | Node.js Training | Intellipaat

Node.js Tutorial | Learn Node.js | Node.js Training | Intellipaat

🔥Intellipaat Node.Js training: In this node.js tutorial you will learn node.js from scratch. You will k...

In this node.js tutorial you will learn node.js from scratch. You will know what is node.js, advantages of it, core modules of node.js, node package manager, how to own module in node.js, local & global packages and how to install node.js in detail.

Why should you learn Node.js?

Node.js has become one of the most widely used JavaScript tools in recent years. Since, JavaScript is known by millions of developers across the world, learning Node.js can take your career to a new level. By equipping yourself with its concept, you can even write JavaScript on the client and server. Plus, it offers a lower learning curve, thus, you can easily become a full-stack developer.

Why Web Development is important?

The web is a dynamic sea of information experiencing rapid expansion. Web developers help make that info accessible, organized, and useful. They also implement new tools and applications every day that enhance pretty much every industry or economic sector you can name.