
Welcome to Node Internals and Architecture course. If you choose this course chances that you have already use Node. This is not a course about how to get started with NodeJS, it is a course to understand everything there is about the internals of NodeJS so you can take advantage of it.
This course for software engineers who use Node and want to take their understanding of this runtime to the next level. Write efficient code, optimize Node, and take advantage of Node various features to unlock potentials.
Because this course will dive into the bowls of the OS, I recommend taking my fundamentals of operating systems.
Explore the Node.js architecture with V8 and libuv, learn about the event loop, io, dns, tcp/udp, http, tls, streams, processes and threads, and master performance optimization and debugging.
Any OS will work, Linux or Mac machine preferred since we will use the various tooling on UNI* not available on Windows.
Node version 20-22
Explore Node.js architecture by examining the JavaScript execution engine and IO within the event loop. Identify phases like timers, poll, check, and promises, and compare require vs import and packages.
We discuss how compiled and Interpreted languages work, and how V8 the engine behind Node can compile javascript to machine code if the function is hot.
This is an overview of the event loop, a critical piece of the Node runtime.
Before anything can run, we synchronously execute all code in the main module before we event start the loop. This is called the initial phase.
Unpack the idle prepare phase in Node's event loop, revealing how libuv prepares for IO by setting up structures like epoll, with a hands-on strace demo of system calls.
Explore the Node.js poll phase as this lecture details how IO events and callbacks execute, the blocking vs non-blocking distinction, and epoll-based async IO with libuv.
Master the check phase in the Node.js event loop, which runs after the poll phase and uses setImmediate to split large callbacks, enabling deterministic, non-blocking IO and predictable output.
The close callbacks phase schedules and finally fires close events for sockets and connections, since closing is an io operation that takes time and may delay pending callbacks.
Explore how Node's process.nextTick runs after every event loop phase, enabling deterministic microtasks, its difference from timers and setImmediate, and the danger of nested nextTick calls.
We explain how promises, async await are callbacks behind the scenes.
Understand require and import in node.js: require loads synchronously at initialization and can be conditional. Import offers asynchronous IO and returns a promise, enabling dynamic loading and error handling.
Node exits when there is no code to execute. While it may appear that we don't have any code executing, Node is working behind the scenes, example is listening, accepting and reading from connections.
We will do an strace to prove that while we appear to not have any code running, Node still does.
Go through the libuv io phases, event loop, thread pool
The OS course
In this lecture we discuss how node performs network io as a client and as a server
show that passing file descriptors are faster.
how it works
reading sync vs async ,
do strace
What is really happening?
Explains how https encrypts http traffic via TLS, covering symmetric and asymmetric encryption and the TLS handshake. Illustrates certificates, chains, root authorities, and Node.js https usage with OpenSSL-generated keys.
Explore how the domain name system translates names to IP addresses, enabling load balancing and geo DNS, and examine how Node.js resolves DNS with host files and the thread pool.
Explore how node's net module implements tcp, covering the three-way handshake, segments, sequencing and acknowledgments, with flow and congestion control for reliable, ordered communication.
We discuss NodeJS streams
OS course
Explore how node's single threaded model uses worker threads to offload cpu work into event loops. Learn to communicate via message channels and workerData to distribute tasks across threads.
Explore Node.js child processes and cluster, comparing processes and threads and IPC. Learn how forking creates independent workers with IPC channels and how scheduling policies like round-robin distribute connections.
Learn to debug Node.js with a compatible debugger, using VS Code and Chrome remote debugging via the inspect protocol. Set up a launch.json, place breakpoints, and inspect responses and variables.
doing a memory and time
Explore building and debugging a C++ add-on for node.js by wiring a two-number add function through napi, using the node API, binding files, and debug across C++ and JavaScript.
Explore Node.js architecture with libuv, the event loop, and V8; dive into internals from file I/O and networking to TLS, streams, clustering, and performance best practices.
My favorite thing in software engineering is the art of making it transparent.
Node is one of the most popular runtimes used on backend engineering yet I feel it is the least understood. I surely felt this way at times.
I spent months working on a course to demystify NodeJS Internals and Architecture and distilled this in this comprehensive course.
I built this course is for the engineers who can't stand working with something opaque.
They love to understand what is running behind the engine.
They enjoy tearing apart 1 the line of code into its original 1000 lines.
They question why is the output of a Node program is unpredictable.
They want to know when does the Node process exit.
They want to know why Node takes so long to start in some cases.
They appreciate how Node works on all operating systems and would like to know how it does that.
For example by understanding the internals of HTTP module, you can write a backend in Node that accepts and process more requests. Every line of code you write you would think of how and when Node will process it.
By understanding the event loop and the different stages you can tune and re-order your code to achieve best performance and even consistent result.
Ever wrote a program in Node that fails 1% of the time while succeeds 99%? Understanding Node architecture helps you make your program predicable. As opposed to adding workaround because you don't understand. We all did that.
It is all about removing blockage and letting the main loop phases “breath”. When we build software the problem is we often go against the grain. Understanding where the friction is in Node allow you to work with it as oppose to against it.
In this course I cover the following
- NodeJS Architecture
I cover the various phases in the event loop and what exactly happens in each phase, how promises are just callbacks, how and when modules are loaded and their effect on performance, Node packages anatomy and more
- Node Internals
This is where we go one layer deeper, how Node truly achieves asynchronous IO with libuv, and how each protocol in node is implemented. How concurrent node works on both user level threads and process level.
- Node Optimization and Performance
Now that we understand the internals and architecture of Node, this is where we discuss tips how to make the code runs more efficiently and more performance. And only when we exhaust all other avenues Node provides ways to extend it with C++ add-ons where JavaScript just can't no longer hold.
This course is for intermediate students who are familiar with Node and want to understand how it works. While not required, I recommend taking the fundamentals of operating system course as a prerequisite of this course.