Node.js is single-threaded. This means that all operations are executed in a single thread.
Node.js applications have a single call stack.
A call stack operates as a queue. During execution, when an application steps into a function (executes the function), it pushes the function into the stack.
When the application steps out of the function (the function returns), that function is removed from the call stack. A call stack records where in the program structure we are at any given time.
Node.js processes are single-threaded in order to avoid the complexity that comes with writing multithreaded code, the Event Loop allows offloading I/O tasks to the C++ APIs.
That allows the core Node.js runtime to continue running your JavaScript code while the C++ APIs are taking care of the asynchronous I/O operations in the background. This creates an imitation of multithreading and the possibility to write non-blocking code.
Node.js sends heavy time-consuming operations such as I/O callbacks to the C++ API and its threads.
This allows the simulation of "multithreading" within a single-threaded Node.js process and allows the main runtime to continue executing our code without waiting.
This gives Node.js the benefits of an asynchronous non-blocking I/O interface.