What Exactly is Node.js? (Keeping it awesomely simple)

What Exactly is Node.js? (Keeping it awesomely simple)

Node.js has grown from it humble beginnings in 2009 to one of the most popular platforms for creating web applications. If you have been around web development for a while, you would have heard people say, ‘node is just javascript’. That’s true, to appreciate node.js, it would help to know what it came to solve and why it is used.

Anatomy of a Web Application

fullstack.png Image courtesy of Medium.com

A functional website is usually made of two parts: the front-end and the backend. Consider facebook.com, the front-end is all what you see when you visit the webpage at facebook.com – the fonts, the colors, the animations – everything you can see and interact with is the front end. The front-end is created using three fundamental technologies, HTML, CSS and Javascript. Javascript is what makes interactivity possible on a website, things like input validation, animation are usually implemented in javascript.

When you perform actions on facebook like creating an account, facebook must ‘keep a record’ of your account and ‘remember’ it next time when you are trying to login. When you are logged in and you are going through your timeline, you see posts from friends – facebook must be able to keep a record of posts made and be able to retrieve them. All this ‘data manipulation’ stuff is done by the backend.

The backend of a website consists of a server, application and a database. The backend developer will build and maintain the technology that powers these three components so that they can work together. Prior to node.js, backend applications have to be written in PHP, java, C# or other technologies. Javascript couldn’t run on servers!

Facebook's backend was originally created in PHP.

request cycle.png A simple request cycle.

Javascript was created to be used in the frontend – web browsers all have javascript engines built in them: Chrome uses the V8 engine, Mozilla uses Spidermonkey engine. So, in the early days, only browsers could run javascript*. Javascript used to be called a ‘client-side’ programming language, as it was only used on the client – the browser.

*Actually, there have been attempts to write javascript on the server

Node.js: Javascript anywhere

bridge.png

Any application that can be written in JavaScript, will eventually be written in JavaScript. - Jeff Atwood

I want you to imagine humans living 50,000 years ago. Suppose the only means of transportation was by road, we could only walk or ride on animals on road, no boats, aeroplanes or any other means of transportation. The early humans were wanderers and would go from place to place looking for food.

Now, a group of humans, about 150, arrived at a river side. On the other side of the river they can see trees with fruits of different kinds but how can they get to the other side? The group leader summons the shaman and tells him to pray to the gods for help.

When the group wakes up the next day, alas! The gods have built a bridge which they can walk on and cross to the other side. Now, not only can they walk on road but can walk over water! Their joy knew no bounds.

ryan_dahl_presenting.png Now, fast forward to 2010 and picture Ryan introducing Node.js a year after creating it. Prior to node.js, javascript could only be run on the browser, that is we could only use it in the frontend but with Node.js, developers can now write server-applications with Javascript!

This meant that developers do not have to change context by learning and working in another language to create a fullstack website(one with frontend and backend), they can accomplish all in Javascript!

The fun fact is that any platform we can get Node.js installed on, we can write applications for that platform in javascript. Node.js is even used to write application on Embedded Systems!

Technical Definition of Node.js

Nodejs.org says:

Node.js is a javascript runtime built on Chrome’s V8 javascript engine.

Being a javascript runtime, it means Node.js let’s run(execute) programs written in javascript (outside of the browser). Node.js is no magic, to interpret javascript code, a javascript engine is required and ‎Ryan Dahl chose the Javascript engine in the Chrome browser – V8.

Note: Browsers are not javascript engines - they have javascript engines in them plus other things, similarly Node.js is not a javascript engine, it uses a javascript engine and has additional parts than just the engine.

You can download Node.js installer for your computer here nodejs.org/en/download

Node.js' Programming Model

A language's programming model defines how developers should write code, what is legal and illegal in the language. Since Node is javascript, it follows that the rules of javascript applies to it too but Node has additional conventions.

Nodejs.org continues by defining Node:

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.

I/O stands for input/output. In a web server, I/O operations includes things like reading from a disk, querying the database, communicating with another web server. A web server will eventually have to execute some I/O. The problem with I/O is that it is slow:

Consider the simplified example of visiting a users profile on facebook

request cycle 2.png

Suppose that reading data from the database takes 600ms and the browser takes 100ms to serve the files. Now, we will consider a situation in which we have two site visitors that are visiting the user's profile - they are both requesting for the profile page. Suppose the second site visitor makes his request 1 ms after the first site visitor

Blocking I/O

User A will get the result 700ms after he makes the request, if the server was written as blocking code.

User B will get the result (700+701)ms, he has to wait for A's request to complete and then wait for his to complete too. Imagine how much time a user would wait if facebook's server follows this model and its billion users have to wait for each other's request to complete.

Non-Blocking I/O

What if the server could handle user B's request while it's waiting for A's request to finish? What if we could handle the request in parallel instead of one after the other? This is how Node.js works (actually, it is how good Node.js code works, one can still write blocking Node.js code).

Javascript and in extension, Node.js is single-threaded - fancy name for 'I can do only one thing at a time', but Javascript let's write asynchronous code - code that make it seems like we are doing things in parallel. This is the model that Node.js promotes and it has mechanisms for writing asynchronous code built into it.

blocking-vs-non-blocking-2.png

Events and the Event Loop

When a user makes a request that the server has to handle, we say an event has occurred in the app. An event indicates that a task is to be done. A server request is an example of events in Node.js, opening/closing a file in node.js, writing to a file are all other examples of events in Node.

When we have asynchronous tasks, that is tasks that do not complete at once, Node has to know which event happened first and in what order they should be completed.

Just like in a bank hall, when customers come in to perform banking operations, they are told to join a queue and the bank teller attends to them one at a time in the order in which they came in. Similarly, when different events occur in a Node.js app, Node uses a queue data structure to keep track of the event in the order in which they were fired. This queue data structure is called the event loop. Node.js is single threaded which in background uses multiple threads to execute asynchronous code.

queue.png Node will continue to check this event loop for the entire life of a process to see if there is any events there. Node executes the event loop when events are still in the queue, each execution of the event loop is called a cycle.

I have only given a simple overview of the event loop, it is more complex than this and I may dedicate a post for it in the future.

What is npm?

Suppose you want to acquire a new Desktop Computer, you can do this in different ways. First, if you have some technical knowledge on the workings of a computer, you can buy the different parts - motherboard, hard disks, power supply and other parts and couple up the Desktop Computer yourself. Or you could just go buy a full set of the Computer and save yourself some calories.

Likewise, when writing Node apps, there are common problems like input/form validation, that someone has written code for and you don't have to implement yourself. You can just get their code and use it within your app. NPM (Node package manage) is an online registry that allows developers share code aka packages. npm is the world's largest Software Registry and it's free to use.

The good news is that npm comes with Node, when you install Node.js on your machine, you have also installed the npm.

What are node modules?

A large app built with Node will definitely contain a lot of code. And you can put all the code in a single file no matter how complex you app is and everything will work fine. But a file with thousands of lines of code will be hard to maintain and understand, isn't it better to split things into different files?

Node modules are javascript libraries(code) which you want to keep together, but which you also want to keep separated from the rest of the codebase so that things are cleanly separated.

These modules can be imported into other files (modules) and be used to architect the whole project. To use a module in another file, you use the require keyword. E.g

var http = require('http');

The http module is a built in module in Node, yes Node has some modules that are predefined and built into it.

When you install a third-party package with npm, the package goes into a folder named node_modules.

Creating a Server in Node.js

The http module can be used to create a simple server that responds to request. The module has a createServer method that takes a function as an argument, this function argument is called the callback.

In the following example, many connections to the server can be handled concurrently. For each connection to the server, the callback function is invoked.

If you have node.js installed on your machine, put this code in a file named index.js:

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

After that, run your web server using node index.js, visit localhost:3000, and you will see a message 'Hello World'.

Conclusion

I hope I have helped to introduce or help clarify what Node.js is, remember to share this post on you social media handles and you can follow me on twitter @solathecoder .

If you want to learn more, get the book Node.js in Practice by Alex Young and Marc Harter, it's one of the best books on Node.js.

Happy Hacking!