DEV Community


Node.js Best Practices — Errors, Code, and Resources

aumayeung profile image John Au-Yeung Originally published at ・3 min read

Check out my books on Amazon at

Subscribe to my email list now at

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some best practices we should follow when writing Node apps.

Handle Errors and Exceptions Properly

We should handle errors and exceptions properly on our Express app.

In synchronous code or an async function, we can use try-catch:

async function foo() {
  try {
    const baz = await bar()
    return baz
  } catch (err) {
Enter fullscreen mode Exit fullscreen mode

If we want to catch errors in middleware, we can create our own middleware to catch errors.

For example, we can write:

function errorHandler(err, req, res, next) {
  res.status(err.status || 500).send(err.message)

Enter fullscreen mode Exit fullscreen mode

We have the errorHandler middleware to catch errors from other middleware that are added before it.

Then we can call router.use or app.use with the errorHandler to handle the error.

Watch Out For Memory Leaks

We should watch for memory leaks so that our app doesn’t run out of memory.

Increasing memory usage is bad if it happens continuously.

This means that the app keeps using memory.

There’re apps like Sematext Agent Express module which lets us watch the CPU and memory usage of our app.

With this package, we can integrate it with:

const { stMonitor, stLogger, stHttpLoggerMiddleware } =

const express = require('express')
const app = express()
Enter fullscreen mode Exit fullscreen mode

We just call stMonitor.start() to start monitoring with Sematext when our app starts.

Other tools like Scout also shows us the memory usage of each line of code.

We can see which ones are using more memory and the times that uses more memory.

These can also monitor each request for performance issues.


We can improve our Express app’s JavaScript code to make it easier to test and maintain.

Pure Functions

Pure functions are functions that let returns something and don’t change any outer state.

If we pass in the same parameters to them, then they’ll always return the same value.

This makes their behavior predictable and simplifies everyone’s lives.

We can create new objects instead of mutating existing objects with pie functions.

Some examples of pure functions in JavaScript include the array instance’s map and filter methods and many more.

Object Parameters

To make working with parameters, we should reduce the number of parameters in our function.

One easy way to do it is to add an object parameter to our function.

Then we can use destructuring to destructure the properties into variables.

This way, we won’t have to worry about the order of the parameters.

For example, we can write:

const foo = ({ a, b, c }) => {
  const sum = a + b + c;
  return sum;
Enter fullscreen mode Exit fullscreen mode

We just take the a , b , and c parameters and use them as variables.

Write Tests

Tests are great for catching regressions.

This way, if we change our code, we can have peace of mind that we didn’t kill any existing code if the existing tests pass.

With JavaScript, there are many test frameworks, including Mocha, Chai, Jasmine, and Jest.

We can use any of them to run test.

With Chai, we can write:

const chai = require('chai')
const expect = chai.expect

const foo = require('./src/foo')

describe('foo', function () {
  it('should be a function', function () {
Enter fullscreen mode Exit fullscreen mode

to import the foo file and run tests on it with Chai.


We should handle exceptions properly.

Also, we can use tests to prevent errors.

Pure functions and object parameters also help us write cleaner code.

Discussion (0)

Editor guide