Skip to content
Muhammad edited this page Aug 9, 2023 · 3 revisions

Node.js is an asynchronous event-driven runtime environment, built on top of the V8 JavaScript engine from Google. Node.js is designed to build scalable network applications. Node.js is created by Ryan Dahl, who made the first ever commit on 16 Feb 2009. His intention of building Node.js was to do event-driven I/O in JavaScript to have server-side JavaScript off the ground. Node.js is a popular choice for building real-time applications, such as chat applications, streaming applications, and web servers. Node.js is also used to build microservices, which are small, independent services that can be easily scaled and deployed.

Features
  • Single-threaded event loop. Node.js uses a single-threaded event loop to handle all of its I/O. This makes Node.js very efficient for handling concurrent requests. Almost no function in Node.js directly performs I/O, only through its event loop.
  • Non-blocking I/O. Node.js uses non-blocking I/O to handle its I/O operations. This means that Node.js can handle multiple requests at the same time without blocking. This is in contrast to today's more common concurrency model, in which OS threads are employed. Thread-based networking is relatively inefficient and very difficult to use.
  • Built-in modules. Node.js has a large number of built-in modules that can be used to build applications.
  • Package manager. Node.js has a package manager called npm that can be used to install and manage Node.js modules.
Benefits
  • Scalability. Node.js is very scalable and can be used to handle a large number of concurrent requests. Primarily due to having single-threaded non-blocking I/O.
  • Performance. Node.js is very performant and can handle a large number of requests per second. Not only accept new connections, but also quickly processes and returns responses.
  • Versatility. Node.js can be used to build a wide variety of applications, including web servers, real-time applications, and microservices.
  • Community. Node.js has a large and active community that provides support and resources for developers.
Drawbacks
  • Memory usage. Node.js can use a lot of memory, especially for applications that handle a large number of concurrent requests. In truth, this is obvious and a non-issue. More concurrent requests accepted only means more memory.
  • Security. Node.js is not as secure as some other programming languages.
  • Learning curve. Node.js has a steep learning curve, especially for developers who are not familiar with JavaScript and its convention of async code execution, e.g. callbacks.
Workarounds for drawbacks
  • Node.js runs on a single CPU core. Node.js being designed without threads doesn't mean you can't take advantage of multiple cores in your environment.
    • Child processes can be spawned by using the child_process.fork() API, and are designed to be easy to communicate with.
    • Built upon that same interface is the cluster module, which allows you to share sockets between processes to enable load balancing over your cores.
    • Conventionally, during deployments on a production environment through Docker, multiple replicas of the Node.js server application is created, often equal to the number of CPU cores of a machine. Then the replicas are mapped to a Nginx load balancer. Note that, in this approach, the cluster module is not used.
  • The worker_threads builtin module creates new processes to imitate a traditional operating system thread, given a piece of code and some data to work with.
// filename: main.js
import * as threads from 'node:worker_threads'

function sumOfNumbers(workerData) {
  return new Promise((resolve, reject) => {
    const worker = new threads.Worker('piece-of-code.js', { workerData })
    worker.on('message', resolve)
    worker.on('error', reject)
  })
}

console.log(await sumOfNumbers([2, 3])) // 5

// filename: piece-of-code.js
import {workerData, parentPort} from 'node:worker_threads'
parentPort.postMessage(workerData[0] + workerData[1]) // 5

Clone this wiki locally