How Node.js Works: A Look Behind The Scenes

Nodejs Feb 15, 2017

Node, V8, Libuv and C++

In other to set the stage for this series we will start by learning a bit about nodejs architecture and I will represent this architecture in terms of node.js dependencies which are just a couple of libraries in which nodejs depend on in other to work properly.

Nodejs runtime has several dependencies and the most important ones are the v8 engine and libuv. Nodejs is Javascript runtime based on google v8 engine and that's why it appears here as a dependency and v8 engine enables nodejs to understand javascript code that we write. The v8 engine is what converts javascript into a machine language that the computer can understand.

But that is not enough to create a whole serverside framework and that is why we also have libuv. Libuv is an open-source library with a strong focus on asynchronous I/O (input/output). This layer is what gives nodejs access to the underlying computer operating system, file system, networking and more. Libuv also implements two extremely important features of nodejs which are the event loop and the thread pool and in simple terms, the event loop is responsible for handling easy tasks like executing callbacks and network I/O while the thread pool deals with heavy work like file access or compression. we will dive deep into this later in this series.

One important thing to note here is that libuv is completely written in C++ and not in Javascript and v8 engine also uses C++ code beside Javascript, therefore, nodejs itself is a program written in C++ and Javascript and not only Javascript as you might expect. The beauty of this is that nodejs packs all of these technologies and gives us access to their functions in pure Javascript. It really provides us with a layer of abstraction in other to make our life a lot easier. This architecture allows us to write 100% pure Javascript code running in nodejs and still access functions for file reading which behind the scene are actually implemented in other libraries in the C++ language.

Nodejs also depends on Http parser for parsing HTTP, C-ares for DNS request stuff, OpenSSL for cryptography and Zlip for file compression. So in the end, we have all these pieces nicely fitted together to give us a lightweight and scalable framework.

Processes, Threads, and The Thread Pool

When we use nodejs on a computer, it means there is a node process running and the node process is just a program in execution. In nodejs, we have access to the process variable and in that process, nodejs run in single thread and a thread basically is just a sequence of instructions. Just imagine a thread as being a box where our code is being executed in the computer processor. Nodejs runs in just one thread which makes it easy to block nodejs application and this is something that is worth noting because this is one of the unique features that nodejs bring to the table. No matter the number of users accessing your application, nodejs only run in one thread and that is why you need to be very careful about not blocking the thread.

What happens in a single thread when we run our application?

Alt Text

So when a program is initialized, all the top-level codes are executed which means all the codes that are not inside callbacks. Next, all the modules that your app needs are required and all the callbacks are registered after all this, the event loop will then start to loop.

But some tasks are really heavy and expensive to be executed in the event loop because they will then block the single thread so that's where the thread pool comes to the rescue. the thread pool is provided to nodejs by the libuv library which gives us four more additional threads that are completely separated from the main thread. We can also configure the thread pool to give us 180 more threads but these four threads are far enough in most cases. The event loop offloads heavy tasks to the thread pool and all this happens automatically behind the scenes. We don't decide what goes into the thread pool as developers this happens automatically and these task that gets offloaded to the thread pool are operations dealing with file system APIs, cryptography, compression, DNS lookup (which basically matches web domain to their corresponding IP address). These are the kinds of stuff that can easily block the main thread and nodejs take care of offloading them into the thread pool automatically this is the most important thing to take note in this part of the series. In the next part we will deep dive into what event loop is all about and why it matters.

You can connect with me via twitter

Calvin puram

I thrive to design and develop ideas into a project that makes life easy, solve problems, and implement innovations.