Skip to main content

Nodejs Best practices

· 4 min read
Sivabharathy
  • Prefer const over let. Ditch the var

Using const means that once a variable is assigned, it cannot be reassigned. Preferring const will help you to not be tempted to use the same variable for different uses, and make your code clearer. If a variable needs to be reassigned, in a for loop, for example, use let to declare it. Another important aspect of let is that a variable declared using it is only available in the block scope in which it was defined. var is function scoped, not block-scoped, and shouldn't be used in ES6 now that you have const and let at your disposal

  • Use proper naming conventions for variables, constants, functions and classes

Use lowerCamelCase when naming constants, variables and functions, UpperCamelCase (capital first letter as well) when naming classes and UPPER_SNAKE_CASE when naming global or static variables. This will help you to easily distinguish between plain variables, functions, classes that require instantiation and variables declared at global module scope. Use descriptive names, but try to keep them short

Example:

// for global variables names we use the const/let keyword and UPPER_SNAKE_CASE
let MUTABLE_GLOBAL = "mutable value"
const GLOBAL_CONSTANT = "immutable value";
const CONFIG = {
key: "value",
};

// examples of UPPER_SNAKE_CASE convention in nodejs/javascript ecosystem
// in javascript Math.PI module
const PI = 3.141592653589793;

// https://github.com/nodejs/node/blob/b9f36062d7b5c5039498e98d2f2c180dca2a7065/lib/internal/http2/core.js#L303
// in nodejs http2 module
const HTTP_STATUS_OK = 200;
const HTTP_STATUS_CREATED = 201;

// for class name we use UpperCamelCase
class SomeClassExample {
// for static class properties we use UPPER_SNAKE_CASE
static STATIC_PROPERTY = "value";
}

// for functions names we use lowerCamelCase
function doSomething() {
// for scoped variable names we use the const/let keyword and lowerCamelCase
const someConstExample = "immutable value";
let someMutableExample = "mutable value";
}
  • Start a Codeblock's Curly Braces on the Same Line

The opening curly braces of a code block should be on the same line as the opening statement

Example:

// Do
function usersList() {
// code block
}

// Avoid
function usersList()
{
// code block
}
  • Require modules by folders, as opposed to the files directly

When developing a module/library in a folder, place an index.js file that exposes the module's internals so every consumer will pass through it. This serves as an 'interface' to your module and eases future changes without breaking the contract

// Do
module.exports.SMSProvider = require("./SMSProvider");
module.exports.SMSNumberResolver = require("./SMSNumberResolver");

// Avoid
module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
  • Use Async Await, avoid callbacks

Node 8 LTS now has full support for Async-await. This is a new way of dealing with asynchronous code which supersedes callbacks and promises. Async-await is non-blocking, and it makes asynchronous code look synchronous. The best gift you can give to your code is using async-await which provides a much more compact and familiar code syntax like try-catch

  • Use arrow function expressions (=>)

Though it's recommended to use async-await and avoid function parameters when dealing with older APIs that accept promises or callbacks - arrow functions make the code structure more compact and keep the lexical context of the root function (i.e. this)

First, let me give you an example of what we’re talking about. The first time I noticed the backlash was the Twitter response to this function:

const secret = msg => () => msg;

It’s equivalent to the following function expression:

const secret = function (msg) {
return function () {
return msg;
};
};

Naming conventions

WhatHowGoodBad
ControllersingularUserControllerUsersController UsersController
Routepluralusers/1user/1
ModelsingularUserUsers
Schemapluraluser_profilesuserProfile
Schema columnsnake_case without model namemeta_titleMetaTitle; user_meta_title
Method/FunctioncamelCasegetAllget_all