NodeJs uses event based architecture for handling tasks. The program will have two sort of tasks, synchronous and asynchronous.
Node executes synchronous tasks in the main thread, and when it encounters an synchronous one, it will invoke the corresponding system API (ie I/O) and registers the call back in the callback queue. In the meanwhile it continue to execute next task. When there are no more tasks to do, meaning that the call stack is empty, the event loop will start popping the callbacks from the queue and bring them to the scope, executing them on the main thread.
Non blocking I/O
Syncronous tasks goes on the stack, synchronous like the I/O goes to the system API (or web API in the browser context), in a non-blocking way, nodeJs once completed places the callback in the callback queue. Once the stack empty, it takes the first thing on the queue and executes it. So the JS runtime is single threaded, but other system API aren’t. They are handled by the system and executes in the C++ runtime.
Single Threaded ?
YES nodeJs receives all HTTP requests using only one thread. It does not mean that the servers waits for the request to finish before serving another.
It just uses Event Queue, the main thread receive the request and queue it to be handled in the event loop and then serves the response once the callback fired. The other system tasks in which node calls C++ code is still multithreaded.