Node.js 101

Node.js 101 - An introduction to Node.js

What is Node.js?

Node.js is a server-side JavaScript platform designed to address a very specific set of use cases. Traditionally, JavaScript functionality has been limited to the front end, forcing it to exist within the browser that is displaying the page. Node.js allows the developer to run JavaScript in the back end, away from the browser.

Node.js interprets and executes JavaScript in the back end using Google’s V8 VM, which is the same runtime environment used by Google Chrome to execute JavaScript in the front end. Google’s engine is considered to be one of the fastest dynamic language runtimes around.

Running JavaScript on the server makes for several advantages over front end execution. Namely, the server can initiate the communication as opposed to the browser. Additionally, the way in which threading and callback loops are executed on a server-side JavaScript platform can provide quicker networking and processing.

Benefits of the platform

In order to adequately evaluate the benefits of the Node.js platform, we must evaluate the platform itself. Node.js is a specialized tool for managing I/O across file systems and networks in much the same way that SASS is a specialized tool for making color a variable in your CSS.

As a network communication tool, Node allows you to implement an application alongside an HTTP server within the platform itself. This is a novel feature among JavaScript platforms, which have traditionally been unable to do so.

“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.” — Node.js Homepage

node.js event loop diagram

Non-blocking I/O: While it doesn’t make I/O operations any faster, this feature does ensure that I/O operations won’t interfere with each other. This means that the server can handle multiple requests at once without bogging down the Node server.

Distributable: Any additional I/O tasks beyond the scope of the application itself, such as network and database calls or filesystem access, are pushed to a worker thread pool. This means that the JavaScript event loop operates on a single thread, while everything else runs in parallel.

Event-driven: This means that you don’t have to rely on the client to make regular interval requests, limiting useless communication between the server and client. More specifically,

End-to-end: Node.js is an end-to-end JavaScript platform in the sense that it can exist on both the client and the server. As such, the view logic of an application can be made available in both locations, meaning it can be rendered by the server on first request, and by the client on every subsequent request.

Low latency: The response latency of a modern web application has become one of the most important factors in determining a user’s experience. Node.js is able to quickly respond to connections in an efficient manner, making it very useful in designing real-time, mobile web apps.

Scalable: The manner in which Node.js handles concurrent connections makes it highly scalable. The server can handle as many or as few connections as is required of it without weighing down the Node server.

The platform also features numerous useful modules, saving you the trouble of having to write everything yourself. This, in turn, means that Node.js is really more than one thing: it’s a runtime environment, but it’s also a library.

Drawbacks of the platform

While Node’s unique design is powerful and elegant, there are also a few drawbacks.

“Clearly, Node isn’t the solution to every problem. It’s obvious that business logic processing with lots of database CRUD, image processing, or any long-running blocking operations are best avoided.” — Node 101 Github FAQ

Beyond the various functionalities that are beyond Node.js’s scope of specialization, there are a few drawbacks that can typically be addressed by the developer. Among the most notable of these drawbacks are control flow, error handling, backend instability, and debugging chaos related issues.

Control Flow: The callback pattern is a powerful approach to asynchrony, however it can cause many issues for the developer – “callback hell” is among the unfortunate side-effects. Node.js supports other control flow patterns that can address this concern, for the most part. The other control flow patterns include events, streams, async modules, promises, and coroutines, to name a few.

Error handling: Each node process is responsible for a huge number of connections, so any unhandled errors could interrupt a large number of connections at once, as opposed to interrupting only the connection experiencing the error. This can be largely mitigated by handling all errors.

Back End instability: Due to Node’s asynchronous handling of incoming requests, high-traffic situations can contribute to backend instability. As more and more incoming requests become delegated to the worker thread pool, the backend can become saturated with too many requests.

Debugging chaos: Due to the relative immaturity of the platform, Node.js almost completely lacks any native debugging tools. Fortunately, tools like node-inspector, DTrace, and V8’s debugger exist to make debugging less of a nightmare.