JavaScript in Plain English

New JavaScript and Web Development content every day. Follow to join our 3.5M+ monthly readers.

Follow publication

Node.js Best Practices for Beginners and Experts Alike

Node js best practices
Node JS Best Practices

Node.js is one of the most popular web development frameworks.

Anyone can fall in love with JavaScript by learning Node.js as it’s purely based on JavaScript.

One can create lightweight, non-blocking, scalable, fast, and robust server-side web applications by writing javascript code outside the browser.

Today, we will discuss some useful Node.js best practices that will help all kinds of developers — beginners and experts — to create an efficient and most sustainable application.

So read ahead!

Restart the app with the help of tools each time you change the code

In the developing stage, the coders stop and restart the application to implement changes made to the code. This can be a hassle, which might lead you to lose focus on the main task.

You can use tools as a solution to this issue and save yourself from restarting the application over and over again to reflect the changes.

Following are the most popular code monitoring packages for Node.js:

  • Forever: It offers an auto-restart feature along with additional configuration such as writing logs and setting work directory that would be printed n stout to a specific file.
  • Nodemon: It also offers an auto-restart option whenever new changes are made to the code. To initialize nodemon, replace node with nodemon on the command lone.
  • PM2: Another process management tool with superb control and features in comparison to the above two.

Forever and PM2 can are suitable even for production environments. It ensures that the code is recovered after a runtime error. It also makes sure that the application restarts quickly in case the server goes down.

Replace callbacks with async/await

Initially, callbacks were used to maintain the asynchronous nature of Node, but it used to lead callbacks to spiral out of control after they are nested continuously. This is the point where code becomes unreadable.

With the introduction of async/await, developers have seen a decrease in this issue. However, to avoid callbacks, one has to ensure to use async/await.

You can easily prevent callbacks hell scenario by replacing callbacks with async and await.

Adopt lowercase

In some programming languages, the filenames must match class names

Avoid doing that in node.js and stick to lowercase.

Node.js is a Linux-centric tool and cross-platform support. However, Windows and OSX will treat uppercase (‘MyClass.js’) and lowercase (‘myclass.js) the same way, but Linux will not. To write code for cross-platforms, you should meet the exact requirement statements, counting capitalization as well.

The best way to do it is by sticking to lowercase only.

App Cluster

Node runtime is limited to a single CPU core, and deploying non-clustered node apps on a huge server could be a wastage of resources.

To make the most out of multiple cores and extended memory beyond 1.5GB, add cluster support into your application. With the help of a cluster, you get the flexibility even if you are running a single process on small hardware.

With thorough testing, you can determine the precise number of clustered processes for an app. However, it’s always a great idea to go with defaults first.

You can avoid rediscovering the process management wheel over and over again by choosing cluster abstraction.

Avoid garbage

Node has a lazy garbage collector with a default limit of 1.5 GB. This garbage collector will wait until it actually has unused memory to reclaim.

If you are getting out of memory, it’s not because of the leak but the lazy behavior of the garbage collector.

However, one can take complete control over their garbage collector by providing flags to V8.

web: node — optimize_for_size — max_old_space_size=920 — gc_interval=100 server.js

Doing this is crucial, especially when you are running a node in an environment, less than 1.5Gb memory.

For example:

web: node — optimize_for_size — max_old_space_size=460 — gc_interval=100 server.js

The above code can be used to customize the node to a 512 MB container.

Clean Code & Easy Readability

There is no doubt that cleanliness helps improve the quality of the code.

Almost every code contains linter and formatter.

Linter searches and warns about syntactically as well as semantically error codes, whereas a formatter works like more stylistic factors to ensure a set of formatting and style is consistent throughout the project.

The most famous linters are ESLint, JSLint, and JSHint.

Most of the IDEs/code editors such as Atom, VSCode (Visual Studio Code), etc. value the quality code and offer linting & formatting plugins that are intuitive and easy to set up.

Not only this, these IDEs offer additional features such as refactorings, intelligent code completion, on-hover documentation support, auto imports, debugging tools, code navigation, and so much more.

So it is highly recommended to get one of these IDEs and set up for a smooth coding workflow.

Dependency Injection Software

This software design advocates injecting or passing dependencies or services as parameters to the modules instead of creating or requiring them.

This fancy term keeps your modules independent, flexible, scalable, and testable across the app.

Imagine you have a module that exposes two functions for dealing with a random Emoji class. It also uses a yellow-emoji module that deals with a yellow emojis data bank.

The issue here is that the setup servers to only one specific set of emojis — yellow. Consequently, if you want to work with a different set of emojis or multiple sets, you would create separate functions or maybe repair the existing one.

That’s why it’s crucial to create functions that work in multiple ways.

With dependency injection, you can make your functions more generic and flexible.

Let’s understand this with an example -

Suppose you create a new function — EmojisService — that will take the dependency — emojiColor — as a parameter instead of fixing to one color type (yellow).

That’s how dependency injection works.

Thanks to this, the service will have a more generic interface that is easy to use and test.

Now instead of creating yellow-emoji to the test case, we can directly pass emojiColor dependency to it.

For more perfection, follow the given practices:

Use Secure, hierarchical, and environment aware Config

The sign of a faultless configuration setup includes: secrets are put outside of committed code, a hierarchical pattern is followed for config for easy search, and keys are readable from environmental variable and file.

Packages such as rc, nconf, config, and convict follow the above-mentioned.

If you fail to meet the config requirements, it will bog down the DevOps or development team or maybe both.

Some Specific Plugins

There are certain plugins that cover vanilla JavaScript, such as eslint-plugin-mocha, eslint-plugin-node, and eslint-plugin-node-security.

However, various faulty node code patterns might skip under the radar; for example, developers might need “variableAsPath” files with the variable as the path, which opens the doors to attackers to execute any JavaScript. Linters can detect these patterns and alarm the developer to take the required action.

Use Helmet for web app

Building Web Applications is so much fun. To make your coding even simpler, secure your application first.

Use:

  • XSS Protection
  • Setting a Context-Security-Policy header
  • Ensure all connections to be HTTPS
  • Avoid Clickingjacking using X-Frame-Options
  • Disable the X-Powered-By header so that the attackers cannot penetrate their attacks to a specific software

If you find it doing the above practices a bit daunting, simply use the Helmet that will set them all to sensible default, and you would be able to tweak the required ones.

Setting up Helmet for JavaScript applications is pretty easy.

All you need to do is just use -

“$ npm install helmet”

In your code and then add -

var helmet = require(‘helmet’);app.use(helmet());

Voila! You are good to go!

Wrapping Up

No coding is difficult until you come across certain errors, and no language is easier until you find the best practices. So use the mentioned Node.js backend best practices in your project and make coding fun.

Build a robust, scalable, and flexible application or software with Node.js.

More content at plainenglish.io

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in JavaScript in Plain English

New JavaScript and Web Development content every day. Follow to join our 3.5M+ monthly readers.

Written by Rencybeth

Conquer on the words. Writer| Designer| Entrepreneur| Business Analyst

Responses (2)

Write a response