What is NodeJS

Chamal Weerasinghe
9 min readOct 15, 2022

I cannot say whether things will get better if we change; what I can say is they must change if they are to get better.” — Georg C. Lichtenberg

Even at this moment, a new JavaScript framework might have launched. In recent years JavaScript becomes a de-facto in the web development world NodeJS is the successor for the great start.

Before jumping into how it happens it is better to know its history. Previously (before 2009 I guess 😉) JavaScript was widely used in front-end development. This includes manipulating client-side data and UI elements also things like animations, validation of client-side inputs, or calculations that are completely based on the browser environment. The reason for that is at that time JavaScript runtime is based on the browser environments. It only has access to the resources provided by the browser. At that time the runtime environment required to compile and run JavaScript programs was browser based. due to this previously, there is a need for a second language for the development of the server side for the web applications (ex — Java, C#), this includes handling database calls, data processing, complex calculations, and third-party server call for other servers.

This is where the NodeJS comes in as discussed before there was runtime even before and the limitation was execution at the browser level NodeJS uses the existing runtime used in Google Chrome (V8 Engine) and added the ability to run the JavaScript codes on the server side. NodeJS mustn't consider a programming language it provides the complete runtime environment to compile the JS program and run the program on a given platform (Linux, macOS, Windows).

NodeJS Architecture

As we discussed the development of NodeJS is mainly based on the Google V8 engine. and the other core part of NodeJS is a library called Libuv which brings some of the core features into the NodeJS development environment. mostly written using C. Soon we discover what is each one’s responsibility and what makes NodeJS somewhat unique.

When compared to other servers like Apache NodeJS has a different implementation. unlike the Apache server, NodeJS is a single-threaded, non-blocking, event-driven architecture. What is meant by these buzzwords? First, let’s peek into the diagram created by Simform.

NodeJS Architecture

After writing the application in JS then it will be compiled into machine code via the V8 engine. And when it comes to running the application we mentioned a few key points and now let’s discuss them in a detailed manner.

Single Threaded - Thread provides the ability to execute a set of instructions independently from one another. But when it comes to the web servers like Apache, and Tomcat when a request comes into the web server it allocates a separate thread for processing the request. (As an example Tomcat gives a thread from its thread pool for every request received by it and releases it when it is done).

This is different in NodeJS works on a single thread. This does not mean that NodeJS has only one thread, the reality is that NodeJS has hidden threads using the “libuv” library. which handles I/O operations, Network requests through these hidden threads but the developer can’t use them to offload CPU-intensive tasks like complex calculations.

Since JS is by nature a single-threaded language NodeJS introduced a concept called “worker-threads” which utilize the cores of the CPU. When a request is received by the NodeJS, it is added to the Event Queue, Then the Event Loop is keep on running and watching for any request on the event queue, if there are any requests on the event queue the event loop gets it and decides whether it is a blocking operation (which uses I/O or Network operations) then it sends it to a worker thread and when it completes its process it sends the signal to the main thread (event loop) that the task is completed and the event loop returns the result.
If the request is a non-blocking event loop completes the process by itself and returns the result. In this mechanism, NodeJS does not wait till another request completes the event loop keeps on running and works only using a single thread.

Non-blocking - As we discussed earlier in a detailed manner the event loop keeps on running indefinitely on a single thread this is the attribute that brings the Non-blocking attribute to the NodeJS environments. What this means is it does not wait for a certain task to be completed, before returning its response or starting other tasks it gets another task from the event queue, and based on the task type, it starts processing them instantly or handing them over to the worker threads. It never blocks the execution.

These non-blocking tasks execute asynchronous execution. Asynchronous executions do not run in the same order the code is written or in sequence order. first, it calls the asynchronous code block and without waiting for the response it moves to the next code block. Here let’s look at an example.

Asynchronous Execution Flow

In the above example, it executes and prints ‘Step 1’ on the console and it does not print ‘Step 2’, since it is an asynchronous block it waits for 4 seconds to return its output, till then it executes the line next to it and prints as ‘Step 3’ and then after prints as ‘Step 2’ when the 4 seconds is completed like below. (Try this code on playcode.io)

The execution order of Asynchronous Code Block

But in the synchronous execution, it just follows the sequential order of how the code is written and if some task takes 4 seconds to complete it had to wait exactly 4 seconds before going to the next step. To learn more about modern JavaScript read my article here.

Event-Driven - An event is an action generated by the Application, user, or system, as example Application completed processing an excel file it creates an event to let the user know it’s completed, user clicks generate data button it triggers an event, or the system generated software or hardware error can also generate events.

In NodeJS it implements something called “Event Emitters” when a certain event has occurred these event emitters emit an event. and the developer implements “Event Listeners” which are listening and reacting to certain event emitters. and event listener calls its associate callback function when an event is triggered from the event emitter to the event listener. this is also known as the “Observer Pattern”.

Most of the NodeJS objects including HTTP requests, and responses are also implemented by inheriting the “EventEmitter” class and it is the core of Node asynchronous event-driven architecture. this built-in implementation allows developers to listen to multiple events using multiple listeners at the same time. This is highly used in chat applications and bi-directional communication also.

Advantages of NodeJS

Ability to serve a high number of requests efficiently using the Event Loop and Event Queue and eliminate the complexity of working and having multiple threads.

NodeJS consume less memory footprint and less startup time, this is useful for microservice applications and when running containerized application. and using fewer server resources.

NodeJS is a completely open-source project with a well-established community almost all the issues developers have to go through can be solved with the community's help and might already be solved by someone else 😉.

NodeJS comes with its package ecosystem NPM(Node Package Manager) which is one of the largest stores of libraries where developers can find libraries/dependencies for their projects without having to write everything from scratch.

NodeJS uses JavaScript anyone who has good JavaScript knowledge working in the front end now can develop backend applications. and for anyone new to JS it has a shorter learning curve and simplicity compared to some programming languages for famous frameworks.

NodeJS is famous for faster web, and API developments and tests so this tends NodeJS adapt to startups where it reduces the application development time.

Drawbacks of using NodeJS

The advantage of being a Single-Threaded comes with a disadvantage too. when NodeJS-based applications start to receive many CPU-bounded tasks like heavy calculations, image compressions, and video compressions still there is delay in the event loop. However, as discussed previously the introduction of “worker threads” is now can leverage additional threads and but this is only effective on machines with multiple cores.

Node Package Manager(NPM) dependency installations are unlike something like maven it usually stores all the dependencies on the project directory itself. there are two projects with similar dependencies it still stores those two dependencies in both directories this takes a lot of storage due to the overgrown nature of the npm dependencies. This issue is addressed by the “pnpm”. where pnpm stores the dependencies on the content-addressable store. But still, there is a bit of a drawback for the people who prefer to use npm over pnpm. But some developers prefer this way and they might not consider it as a drawback.

Another disadvantage developers face when developing asynchronous execution using promises is called the famous “callback hell” issue. This issue is considered to occur due to bad programming practices. When the developer writes code where it first resolves a promise and then after resolving or based on the error the code branches into the next level just like that this is keep nesting which makes code harder to maintain and consider bad practice. However, this is also avoidable by using promises.

Callback Hell! Image from http://callbackhell.com/


NestJS Docs

When you are writing applications in NodeJS and managing a proper structure for the project might differ from one organization to another or depending on the person it might change.
As a solution for that NestJS provides a great architectural and structural pattern when developing applications by providing a common architectural pattern that everyone on the development team despite the organization can rely on NestJS structure, This might be not 100% the same everywhere, but it provides clean code and structure at a very significant level. Also, the CLI equipped with the NestJS allows developers to generate modules, services, and many more without having to create them from scratch.

It uses TypeScript by default to ensure type safety. and if you are coming from Java, or C# this would be easier to grab with a shorter learning curve.

If you are thinking of doing developments in NodeJS and if you are coming from Spring Boot or Spring environment or ASP.NET, if you have experience in Angular development (Not necessary), there is a great framework for building scalable microservice and web applications.

one thing I highly prefer is GraphQL application development with NestJS, NestJS is a great way to start. It is way easier to develop using Code first and schema-first approaches in no time! it is very easy. and it has great documentation too!

Where Next?

NodeJS is proven its ability to develop from lightweight to heavy applications from Netflix, and PayPal to NASA. Startups tend to use NodeJS for the development of their applications because of the faster development. And because of the lightweight nature of NodeJS, it has also been used to write not only on web servers but also for IoT.

However, NodeJS is not the only JS runtime environment that exists. The original creator of NodeJS Ryan Dhal recently created a similar solution which he addressed as an alternative to NodeJS called Deno. which developed security in mind and out-of-the-box TypeScript support, also running on Google V8 engine.

Also, there is Bun a recent JS runtime environment running based on Apple's JavaScript Core engine currently in development at promised performance increase which exceeds both NodeJS and Deno. “Bun is developed by Jarred Sumner.