Intro to how NodeJS works - Part 1
Happy new year!
This year’s the year when vaccines roll out, typescript gets widely adopted and you learn in depth about how NodeJS
works. Atleast scratch the surface of it’s internals.
Let’s dive right in.
What is NodeJS?
According to the Node foundation themselves,
Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
In simple words, NodeJS is a runtime (think framework) that utilizes V8 engine (think another framework) to help you write OS level operations like accessing files from disks, writing into files, performing networks requests and other I/O operations, all in javascript.
Traditionally, C++ was the preferred way (still is, I guess) to perform OS level operations due to high performance of the C++ language. However with the rising popularity of javascript language, developers came up with a way to perform the same operations by writing JS code.
Today, you can write a few lines of javascript to create a file,read/update it and finally delete it without having to write complicated, error-prone C++ code.
The NodeJS structure
The above image depicts the high level overview of how NodeJS is structured. We write our javascript code in NodeJS, which in turn is executed by the V8 engine and another important module (library) libUV
which is finally executed by the OS (Windows/Mac/Linux).
So how does the V8 and libUV modules fit into the javascript world of NodeJS? Read on!
V8 + libUV = Transpile, Execute, Respond
NodeJS is almost 50% javascript
and 50% C++
. Actually, it’s also some more languages like Python,C,HTML etc. (just check the GitHub repo of Node), however, the point is NodeJS is not completely written in javascript.
The job of NodeJS is more like a wrapper around the implementation of OS specific functions like file access and other I/O.
So, for example, when you make use of the popular inbuilt module fs
for writing to files and write the code to write some content into a text file, NodeJS enables you to write the code in javascript, then delegates the rest of the job of transpiling (converting) the code to C++/C as understood by the underlying OS to Chrome V8 engine, which then delegates the job of actually performing the system call(s) of making a text file, opening a file descriptor socket, writing the content into this socket, closing the connection and returning status (success/failure) of file write back to V8 and finally NodeJS to libUV.
Thus, V8 works like that of a transpiler while libUV is the heart of the NodeJS runtime that actually performs the OS level operations.
And as goes with tradition, libUV is written completely in C++
as is preferred for performing OS level operations. V8 is mostly written in C++ with some parts in JS. The below image concises the different language contributions of each modules of the NodeJS runtime:
Meeting the best of both worlds
So far NodeJS allows developers to write javascript code that are essentially boiled down to C++ code to perform system level operations in speed. Pretty cool, but how does the JS world meets the C++ world?
More precisely,at which stage of the whole process (as mentioned above)?
As you may (or may not, no worries!) have guessed, the V8 engine serves as the boundary between the JS world of NodeJS runtime wrapper and C++ world libUV library. It is here where the values and instructions written in javascript are converted to values and instructions as understood by C++.
Now, consider the following code snippets. First one is written in javascript while the second one it’s C++ equivalent.
//variable initialization
const integerValue = 10;
var otherValue = 20;
//print return value of performOperation()
console.log(performOperation(integerValue,otherValue));
// definiton of performOperation()
function performOperation(firstParameter,secondParameter){
return firstParameter+secondParameter;
}
//variable initialization
int integerValue = 10;
int otherValue = 20;
// definiton of performOperation()
// Note: C++ requires defining the function
// before calling it, unlike JS.
int performOperation(int firstParameter,int secondParameter){
return firstParameter+secondParameter;
}
//print return value of performOperation()
cout<<performOperation(integerValue,otherValue);
The point of showing the snippets is to identify how similar both the worlds of JS and C++ are, atleast on a syntactic level. Yes, they perform differently, they’re compiled differently etc. but undertand this — if you and I can perform mappings between these two languages just by looking at the code, it musn’t be that hard a task to be performed by the V8 engine. Atleast, it’s doable.
NodeJS’ twoface and conclusion
Wrapping up part-1 of this NodeJS series, you can learn more about NodeJS runtime at their official GitHub repository. It’s open source, right?
If you’ve a quick look in this repo, you’ll find two important directories — src
and lib
. The lib folder is the JS side of NodeJS while the src is the C++ side of it.
For example,for the standard NodeJS library’s crypto
module having the function pbkdf2
, you can find it both in lib folder as well as src folder. Ofcourse, the src folder contains the actual implementation of this function written entirely in C++.
Happy exploring!