NodeJs Architecture (Internals)

About NodeJS
NodeJS is a runtime environment for Javascript. Initially, we could run JS code only in browser but nodeJS allowed us to run the code outside browser. It was created by Ryan Dahl in 2009. In it's starting days nodeJS was only available for unix based systems (like linux, macOS). But there was a huge demand for nodeJS by window users, the nodeJS team then updated the code and launched nodeJS for windows, this update was a massive update, imagine it like lifting up a building and construct and put extra floors underneath it. After that, nodeJS became more popular and companies like Netflix, Uber, Walmart and many other started using it.
NodeJS And it's Components
NodeJS is a runtime environment for JS means we can run the JS code using nodeJS. Let's find out what are the different components present inside NodeJS which executes our JS code.
V8 engine: Created by google to run JS inside browser. NodeJS extracted this v8 engine and used this engine to compile JS code inside nodeJS.
NodeJS Core Modules: It have many modules like fs, http, path, crypto & many more.
Bindings: These bindings connect JS code with C/C++ libraries like libuv.
libuv: C library used for event loop, thread-loop, os level async io etc.
These are the components present inside nodeJS which runs our JS code outside browser (server-side).
V8 Engine (The executer):
V8 engine is the component which understand the js code and convert it into machine code so that our OS can understand it and can run it.
V8 uses JIT( Just-In-Time compilation) technique to convert the JS code into machine code.
Let's see the flow of the program.
Developer runs JS code using node command.
V8 first parses it and generate byte code.
The program starts running.
If some function run many time(hot code), JIT compiles them into optimized machine code.
This is the high level flow of the JS code.
NodeJS Core Modules (The pre-written code):
NodeJS core modules are the pre-written code for different functionality like for accessing file system there is fs, for http there is http, https modules. These module get installed inside your system when you install nodeJS and whenever you run any JS code using node command your system searches for that command finds the PATH for it there it finds all the modules then it execute those code accordingly.
For Curiosity, if you want to see the code of core module you can visit nodeJS github repo inside lib directory you will see fs, dns, http etc.
Link: NodeJS Gituhub Repo
NodeJS Bindings (The Bridge):
NodeJS Binding act as bridge between Javascript code to communicate with native system libraries. As you all know now that javascript is a language running in Javascript V8 engine so it does not have operating systems API's. Here, the role of bindings comes, the JS code with the help of these C/C++ bindings call native libraries, like libuv. These libraries are now responsible for completing tasks which Javascript is unable to do.
Just a code snippet from nodeJS lib/fs.js file.
function readFile(path, options, callback) {
callback ||= options;
validateFunction(callback, 'cb');
options = getOptions(options, { flag: 'r' });
ReadFileContext ??= require('internal/fs/read/context');
const context = new ReadFileContext(callback, options.encoding);
context.isUserFd = isFd(path); // File descriptor ownership
if (options.signal) {
context.signal = options.signal;
}
if (context.isUserFd) {
process.nextTick(function tick(context) {
FunctionPrototypeCall(readFileAfterOpen, { context }, null, path);
}, context);
return;
}
if (checkAborted(options.signal, callback))
return;
const flagsNumber = stringToFlags(options.flag, 'options.flag');
const req = new FSReqCallback();
req.context = context;
req.oncomplete = readFileAfterOpen;
binding.open(getValidatedPath(path), flagsNumber, 0o666, req);
}
See in the last line fs module's readFile method is invoking binding (binding.open(getValidatedPath(path), flagsNumber, 0o666, req)).
Now inside these bindings somewhere they are going to call this function uv_fs_read(...)
Libuv (The Base):
Libuv is the C library used by nodeJS to handle asynchronous operations and event loop.
These are some main functionality of libuv
Event Loop
Asynchronous I/O
Thread Pool
Timers
DNS lookups
Networking sockets
This library handles all these above mentioned task for nodeJS . Libuv have thread pool of 4 by default. If there more async task comes the libuv put them in thread queue whenever any thread become available then it is assign it with the new task.
Complete Flow (will increase your understanding)


