Node.js is a runtime that allows JavaScript to run outside the web browsers for server-side development. It is fast, scalable, and built for handling multiple tasks efficiently.
- Built on Chrome’s V8 engine and created by Ryan Dahl.
- JavaScript normally runs in browser like Chrome (V8) and Firefox (SpiderMonkey).
- Enables JavaScript to perform system-level operations like file handling.
- Uses asynchronous and non-blocking architecture.
- Works on a single-threaded event loop for better performance.
- Handles multiple requests simultaneously with minimal resources.
- Ideal for real-time applications like APIs, chat apps, and streaming services.
Npm in Node.js
NPM (Node Package Manager) is a tool that comes with Node.js and is used to manage project dependencies and configurations.
- Installed automatically with Node.js and used to manage packages.
- npm init initializes a project and creates a package.json file.
- package.json stores project metadata, dependencies, scripts, and configuration.
Node.js Request Handling Process
Node.js handles client requests using an event-driven architecture with the Event Loop and Thread Pool to ensure efficient and scalable performance.
- The client sends a request to the Node.js web server.
- The request can be blocking (synchronous) or non-blocking (asynchronous).
- Node.js receives the request and places it in the Event Queue.
- The Event Loop continuously checks the queue and processes requests in FIFO (First In, First Out) order.
Request Processing
Requests are handled differently based on whether they are blocking or non-blocking.
- If the request is non-blocking, it is processed immediately and the response is sent back to the client.
- If the request is blocking, it is sent to the Thread Pool.
Node.js is often described as single-threaded, but this is only partially true. While it uses a single main thread to execute your JavaScript code, the runtime as a whole is multi-threaded behind the scenes to handle background tasks
Thread Pool Handling
Manages blocking tasks in a web application by assigning them to available threads for execution.
- The Thread Pool contains a limited number of threads.
- If a thread is available, the blocking task is assigned to it.
- Once completed, the result is returned to the Event Loop, which sends the response to the client.
- If all threads are busy, new blocking requests must wait in a queue.
Note: A thread is like a worker that processes blocking tasks so the main application can continue running smoothly.
Blocking or Synchronous Operation
In a blocking or synchronous operation, tasks are executed one after another, and the program waits for each task to complete before moving to the next.
- Tasks are executed in a fixed sequence.
- The program waits until the current task is finished.
- Time-consuming operations can delay the entire program.
- Simple to understand but less efficient for multiple requests.
Example to understand synchronous operations:
Reads a file synchronously using fs.readFileSync() in UTF-8 encoding and blocks execution.

Shows the output of the file after it is completely read.

Adds logs to demonstrate how execution pauses during file reading.

Displays execution oreder, confirming synchronous (blocking) behavior.

Non-Blocking or Asynchronous Operation
In a non-blocking or asynchronous operation, tasks are executed without waiting for previous ones to complete, allowing efficient handling of multiple operations.
- Tasks run in the background without blocking execution.
- Improves performance by handling multiple operations simultaneously.
- Uses callbacks or promises to handle results after completion.

- Uses fs.readFile() which executes asynchronously without blocking the program.
- Logs "2" and "3" are printed before the file content.
- File content is printed later through a callback function.
- Execution continues while the file is being read in the background.
- Demonstrates non-blocking behavior where tasks run concurrently.