You shouldn’t start applications through npm when you have child processes natively supported by Node.js. In this article, we will provide a list of best practices for Node.js applications with a code snippet that outlines the core problem and shows you how to reproduce the issue in 3 steps. In short, we stopped using npm start to run our blockchain’s core and instead opted for using the native node command.

Introduction to npm and its most well-known command ‘npm start’

Npm is the go-to node package manager when you are working on a JavaScript project. It allows you to install other people’s code packages into your own project so you don’t have to code everything you need from scratch. Npm also became famous because of its industry-wide usage of script commands that can be entered in the shell to start your application. Of course, the most well-known command is npm start that acts as a wrapper for node app.js .

Our challenge: npm runs app.js files as a child process of npm

However, what many don’t know is that while using npm start to trigger node app.js, npm is actually running your app.js file as a child process of npm which manages this. In 99% of the cases, you shouldn’t care about this, but things can get tricky when working with child processes in your own project. Can you feel the inception happening here? #child-process-inception

If you want to know more about Lisk first, check out this short explainer clip and our documentation!

To give you a better understanding of how this is relevant to our “npm vs node” problem, let’s talk about how we are running Lisk Core. For those who don’t know what Lisk Core is, essentially, it is a program that implements the Lisk Protocol which includes consensus, block creation, transaction handling, peer communication, etc. Every machine must set it up to run a node that allows for participation in the network.

Intro to PM2, a production process manager for Node.js apps

In our case, we use PM2 to restart the application upon failure. PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

A few weeks ago, we decided to provide the ability to run the http_api module as a child process to improve the overall efficiency of the Lisk Core application while using the same allocated resources.

Rationale behind the decision to run http_api module as a child process

The idea behind this decision was mainly funded by the fact that functionally isolated components can form the basis of a multi-process application, in order to utilize the potential of multiple hardware cores of the physical processor if available. Also, to design each component in a resilient way to tackle brittleness of the multi-processing. This means that a failure of one component will have minimal impact on other components and that components can recover individually. More information about child processes can be found in our proposal to introduce a new flexible, resilient and modular architecture for Lisk Core.

We were not able to gracefully exit Lisk Core with npm

While implementing child processes for the http_api module, Lightcurve Backend Developer Lucas Silvestre discovered that Lisk Core was not exiting gracefully while running the http_api module as a child process using PM2. This resulted in a tricky situation where the http_api kept on running in the background whenever the main process (Lisk Core) crashed.