Node.js is a JS runtime library. Node.js uses v8 engine created by Google, the engine takes the JS code and compiles it into machine code. Node.js is basically for running and working in JS on the server end. Node.js doesn’t run on the browser.
V8 is written in C++.
Node.js used to build utility script used in frameworks like React.
Node.js’s role in web development:
- Run server: Create server and listen to incoming requests.
- Business logic: Handle requests, validate inputs, connect to database.
- Responses: Return responses(rendered HTML, JSON, XML).
Alternative to Node.js would be Python, ASP.net, PHP, Ruby
One big advantage for Node.js is it uses JS and for the server side code, it doesn’t require any other language separately other than JS unlike other runtime libraries.
HTTPS ⇒ hypertext transfer protocol secure
Core modules of Node.js:
fs ⇒
path ⇒
OS ⇒
http ⇒ launch a server, send requests
https ⇒
Request and Response header types:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers
Node.js only uses a single thread of my operating system.
Event loop automatically starts when my program starts.
Worker pool use to do the heavy lifting as it used to designate each request into different threads.
Event loop handles all the callbacks. It first executes Timers, then check for pending callbacks.After executing callbacks it enters into a Poll phase.
https://nodejs.org/dist/latest/docs/api/
https://nodejs.org/en/learn/getting-started/introduction-to-nodejs
https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick
https://nodejs.org/en/learn/asynchronous-work/dont-block-the-event-loop
- Syntax errors
- Runtime errors
- Logical errors
-
Single -threaded , Event driven architecture
Single-threaded: Normally, many programming environments use multiple threads (or workers) to handle tasks, especially when doing lots of things at once. Node.js, however uses just one thread. It can do this because it relies on something called Event Loop to manage multiple tasks without needing multiple threads.
Event-driven: Think of Node.js as someone who’s great at multitasking. Instead of waiting for one task to finish, Node.js can start a task, move on to the next one, and check back on the first task when it’s done. This is all thanks to its event-driven nature.
-
Event loop
The Event Loop is what makes Node.js able to multi-task. Here’s how it works:
- Timers: Handles scheduled tasks, like setTimeout and setInterval.
- Pending callbacks: Deals with tasks that are delayed until the next loop.
- Poll: Listens for new tasks, such as reading from files or receiving data from internet.
- Check: Run callbacks from setImmediate.
- Close callbacks: Handles events like closing a file or network connection.
-
Non-blocking I/O
Non-blocking means Node.js doesn’t wait for tasks to finish before moving on the next one. For example , if Node.js asks for data from a database, it won’t sit and wait for that data. Instead, it’ll move on and handle other tasks until the data is ready.
This makes Node.js very efficient at handling many requests at once. Rather than pausing, it’s constantly moving from task to task, which helps make your application faster and more responsive.
d. V8 Javascript engine
Node.js is built on V8, the same engine that powers Google Chrome. V8 takes Javascript code and quickly turns it into machine code that your computer can understand. This makes running Javascript really fast.
Garbage collection: V8 also automatically cleans up unused memory, so you don’t have to worry about your application running out of memory as it runs.
Just-in-time(JIT) Compilation: V8 compiles Javascript on the fly while your app runs, which helps make it even faster.
In Node.js, modules refers to JavaScript files that contain reusable pieces of code, such as middleware, routes, controllers, utilities and configurations. These modules help organize an application into smaller, manageable chunks, making the codebase more modular, readable and maintainable.
Types of modules in Node.js
- Core modules (http, https, fs, path, URL, Crypto etc.)
- Third-party modules (express, body-parser, doteny etc.)
- Custom modules
Node.js provides a set of core modules that allow you to perform essential tasks such as-
- Handling files
- Creating web servers
- working with file paths.
These modules are built into Node.js, so you don’t need to install them separately. Let’s go through some of the commonly used core modules with beginner-friendly examples:
- File system (fs)
const fs = require("fs");
//read a file
fs.readFile("example.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
//write to a file
const content = "Hello Node.js";
fs.writeFile("output.txt", content, (err) => {
if (err) {
console.error(err);
return;
}
console.log("File created successfully.");
});b. HTTP
const http = require("http");
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-type", "text/plain");
res.end("Hello Node.js");
});
server.listen(5174, () => {
console.log("Server running at http://localhost:5174");
});c. Path
const path = require("path");
const directory = "/user/local";
const fileName = "example.txt";
const fullPath = path.join(directory, fileName);
console.log(fullPath);d. OS
//os
console.log("Platform:", os.platform());
console.log("CPU Architecture:", os.arch());
console.log("Total memory:", os.totalmem() / 1024);
console.log("Free memory:", os.freemem() / 1024);e. URL
//URL
const url = require("url");
const myUrl = new URL("https://example.com:8080/path/name?query=hello#hash");
console.log("Host", myUrl.host);
console.log("Path", myUrl.pathname);
console.log("Search Params", myUrl.searchParams.get("query"));f. Crypto
//Crypto
const crypto = require("crypto");
const hash = crypto.createHash("sha256");
hash.update("Hello Node.js");
console.log(hash.digest("hex"));Note: You’ll a run-time error in integrated terminal as "Digest method not supported". This issue typically occurs in newer Node.js versions (Node 18+ which use OpenSSL 3.0) due to security enhancements that disable older, less secure hashing algorithms like MD4 or older versions of MD5.
Here are the primary solutions:
1. Configure Node.js to use the legacy OpenSSL provider
This is a quick workaround if an immediate update of dependencies is not possible. It tells Node.js to allow the use of older, less secure algorithms.
For command-line execution:
export NODE_OPTIONS=--openssl-legacy-provider
# Then run your command, e.g.,
npm start
On windows Command Prompt :
set NODE_OPTIONS=--openssl-legacy-provider
npm start
on Windows(Powershell) :
$env:NODE_OPTIONS="--openssl-legacy-provider"
npm start
For Scripts in package.json : Modify the script to include the option:
"scripts": {
"start": "NODE_OPTIONS=--openssl-legacy-provider node your-app.js",
"build": "NODE_OPTIONS=--openssl-legacy-provider webpack build"
}
Note: For cross-platform compatibility in package.json scripts, a tool like cross-env is recommended.
2. Update your dependencies
The best long-term solution is to update the problematic packages to versions that support OpenSSL 3.0 and use modern, secure digest methods.
- Identify the dependency causing the issue. The error stack trace should indicate which package is making the problematic crypto call.
- Update that specific dependency, or all project dependencies:
npm update <package-name>
# or to update all
npm update
3. Reinstall Node modules
Sometimes the issue can be resolved by performing a clean reinstall of all project dependencies.
- Delete the
node_modulesfolder andpackage-lock.json(oryarn.lock) file.
rm -rf node_modules package-lock.json
# or for yarn
rm -rf node_modules yarn.lock
- Reinstall the packages:
npm install
# or
yarn install
This may pull in newer, compatible sub-dependencies if the project's version ranges allow.
4. Correct a typo in the code
Ensure the name of the digest method passed to crypto.createHash() is valid and spelled correctly (e.g., "SHA256" instead of "sha265"). Node.js supports standard algorithms listed in the Node.js documentation.
5. Downgrade Node.js (least recommended)
If all else fails and you are blocked, you can temporarily downgrade your Node.js version to v16, which uses an older OpenSSL version. This is not recommended for production environments as it involves running on an older, potentially unsupported version of Node.js.
A cryptographic hash algorithm is a one-way mathematical function that converts any input data (message, file) into a fixed-size, unique string called a "hash" or "message digest," acting as a digital fingerprint to ensure data integrity, verify authenticity (digital signatures), and securely store passwords by making data tamper-evident and irreversible. Key properties include producing different hashes for slightly different inputs (avalanche effect) and being computationally hard to reverse or find collisions (two inputs with the same hash)
A stream is an abstract interface for working with data that is ‘streamed’ in chunks, rather than being read or written all at once.(It’ll help to save system memory)
Streams in fs module follow the Node.js stream API:
- Readable streams: for reading data.
- Writable streams: for writing data.
- Duplex streams: Both readable and writable.
- Transform streams: Duplex streams that can modify or transform the data as it is written and read.
Piping streams in Node.js allows you to efficiently transfer data from one stream to another, processing it in chunks.
//Piping stream
const readableStream = fs.createReadStream("example.txt");
const writableStream = fs.createWriteStream("example-output.txt");
readableStream.pipe(writableStream);
writableStream.on("finish", () => {
console.log("File copied successfully");
});readline module reads a file line by line and entire performance in memory saving.
const readLine = require("readline");
const readableStream = fs.createReadStream("example.txt");
const rl = readLine.createInterface({ input: readableStream }); // to read line by line
rl.on("line", (line) => {
console.log("Line:", line);
});
rl.on("close", () => {
console.log("Finished processing the file");
});Working with directories in Node.js involves using the fs(File System) module to create, read, update ,delete and manage directories. The fs module provides both synchronous and asynchronous methods to handle directory-related tasks.
-
Creating a Directory
You can create a new directory using:
- Asynchronous: fs.mkdir()
- Synchronous: fs.mkdirSync()
-
Reading a Directory
Use fs.readdir() to list the contents of a directory.
-
Checking if a directory exists
Use fs.existsSync() or fs.access() to check if a directory exists.
const dirName = "newDirectory"; if (fs.existsSync(dirName)) { console.log("Directory exists"); } else { console.log("Direcrory does not exist."); }
-
Removing a Directory
To delete a directory, use:
- Asynchronous: fs.rmdir()
- Synchronous: fs.rmdirSync()
When the Direcory is empty: fs.rmdir("newDirectory", (err) => { if (err) { return console.error("Error removing directory", err); } console.log("Directory removed successfully."); });
If the Directory has content inside: fs.rm("newDirectory2", { recursive: true }, (err) => { if (err) { return console.error("Error removing directory", err); } console.log("Directory removed successfully."); });
Note: If
true, perform a recursive directory removal. In recursive mode, operations are retried on failure. -
Renaming a Directory