DEV Community

Cover image for Debugging Node Applications
Marcell Cruz
Marcell Cruz

Posted on

Debugging Node Applications

Let's start with an example file so we can test it out, create a file called "test.js" and insert the following code.

let x = 5;
Enter fullscreen mode Exit fullscreen mode

Now we can run it with the "inspect" keyword

node inspect test.js
Enter fullscreen mode Exit fullscreen mode

The debugger will stop in the first line of code, as you can see in the picture. The little arrow > represents where you're right now, and you can also see some code around it, if you ever find yourself lost, type list(10) and hit enter to show 10 lines around where you are, you can increase the number of lines to have a better view of the code.


From here you can type:

  • c to continue, this will make the debugger stop in the next "debugger" keyword.
  • n, to move to the next line or next debugger keyword(more on this later). now type n to move out of the declaration of the variable "x".

Inspecting variable values

You can inspect variables values by typing "exec " in our case we want to know the value of the variable x, so we type exec x and hit enter


You can use exec to run and print any code that you want. For example, you might wanna know the result of x + 5, you can type it in exec x + 5 and hit enter to see the result


Nothing that you type in the debugger will change your code in any way so you can play around and do whatever you want. In this case, the result will 10 of course. You use the exec call to do any type of complex code execution with the value of your variables, functions anything..., to identify bugs and test possible solutions to your code, let's see a more concrete example.

Using code inspection to write code.

Create a file named "test2.js" and place the following code

let users = [
    id: 1,
    name: 'John'
    id: 2,
    name: 'Mary'

const findUser = (users, userName) => {
  return users;
Enter fullscreen mode Exit fullscreen mode

So now let's say you wanna write this "findUser" function but you don't know exactly how to do it, or what it will be the best way of doing it.
We can use the node inspect to test things out quickly and finish writing our findUser function.

node inspect test2.js
Enter fullscreen mode Exit fullscreen mode

Now press "n" until you get where the findUser function is being called.


Here you can test different expressions quickly to find the best way to implement what you want. Let's say you had the idea to use "filter" but you're not sure how to do it, using exec you can quickly play around with the users variable and arrive to the solution, which would be something like this.

exec users.filter(user => == 'John')[0]
Enter fullscreen mode Exit fullscreen mode

and you can also of course check the results in real-time.


The advantage of doing this over just writing the code in the file, is that you considerably reduce the feedback loop of writing something and see the result which will in turn decrease the time that you take to write code. Not only that and much more important is that you have the correct "state" of the app, so you don't need to keep in your mind the state of the app at that moment, you can just write the code that you think will solve the problem, and see the result for yourself.

The REPL(Read, Evaluate, Print Loop)

The REPL is a just an easier way to do what we did above without having to write exec all the time, you can enter the REPL by typing repl and hitting enter, and you can exit by pressing CTRL+c, the picture below is the same thing that we did before but using the repl instead of running exec.


Using watchers

The last useful piece to debug your code is using watchers, watchers are just a more convenient way to check the values of an expression, the following code is just a simple function that changes the balance of the user. Create a file called test3.js and place the following code.

let users = [
    id: 1,
    name: 'John',
    balance: 100
    id: 2,
    name: 'Mary',
    balance: 200

const changeBalance = (userId, amount) => {
  for(let user of users) {
    if( === userId) {
      user.balance += amount;

changeBalance(1, 100);
changeBalance(2, 100);
changeBalance(2, -100);
changeBalance(1, -200);
Enter fullscreen mode Exit fullscreen mode

As we did before run this file with

node inspect test3.js
Enter fullscreen mode Exit fullscreen mode

The code will stop in the first line as expected, now we can create a watcher to watch the balance of the users, let's say we want to watch how John's balance changes over time.
You can pass any expression to the "watch" function, we know that John is the first user in the array so if we want to watch how his balance changes over time we can write

Enter fullscreen mode Exit fullscreen mode

and hit enter, you should see something like this
Now every time you use any command to change the line where you're in the debugger a new item will appear on top of the debugger with the resulting values of all the watchers that you've created until now


In the above image, you can see that the line "0:" represents the watcher that you've created, "users[0].balance = 100" so John starts with 100 dollars in his balance, you can keep pressing n to go through the code and every time the debugger moves the expression will be re-evaluated with the current value if you also want to watch how "Mary" balance changes over time you can create a watcher for her just like you did for John

Enter fullscreen mode Exit fullscreen mode

If you don't want to watch the expression anymore you can unwatch the expression with unwatch('users[0].balance') in John's case.

You can also debug with Chrome DevTools but I wouldn't recommend it because it's harder to set up slower and adds no real advantage, If you're interested in learning more you can read more about it here.

Have a great day 😄

Top comments (0)