Node.js: the JavaScript runtime environment at a glance
When using server-side programming languages such as C or PHP, programming code is generally processed sequentially. This means that a server only begins executing a new instruction in the code when the previous instruction has finished and the result has been delivered. This is also known as synchronous processing. Carrying out further commands is blocked until the current process has ended. This can lead to significant delays, particularly with complex actions, such as accessing file systems, databases, and web services.
Many programming languages, runtime environments, and applications based upon them support the option of performing parallel processing, known as threads. These are individual threads of commands, which can be used to process a series of actions while the rest of the code can continue to be executed. There is, however, one great disadvantage of this method: the more threads that are started, the more CPU time and RAM is required. In other words, multithreading is resource intensive. Furthermore, multithreading is significantly more difficult to program. These problems can be avoided, however, with a server-side implementation of JavaScript. The basis of this is provided by Node.js.
Many programming languages, runtime environments, and applications based upon them support the option of performing parallel processing, known as threads. These are individual threads of commands, which can be used to process a series of actions while the rest of the code can continue to be executed. There is, however, one great disadvantage of this method: the more threads that are started, the more CPU time and RAM is required. In other words, multithreading is resource intensive. Furthermore, multithreading is significantly more difficult to program. These problems can be avoided, however, with a server-side implementation of JavaScript. The basis of this is provided by Node.js.
What is Node.js?
Node.js is a software platform with event-based architecture, which enables to use JavaScript, the scripting language originally developed for client-side use, on the server side. This means that thanks to Node.js, JavaScript can perform similar tasks than PHP, Java, .Net, Ruby, and Python. Node.je is used for the development of server-side JavaScript applications, which need to manage large amounts of data in real time. It is a particularly popular runtime environment for realizing lightweight web servers.
The development for this cross-platform software project was started by Ryan Dahl in 2009 and it is based on Google’s JavaScript Engine V8, which is also used in the Chrome web browser. Launched by the company, Joyent, the project has been run since 2015 by the Node.js Foundation, a Linux Foundation project. Current versions are available for Microsoft Windows, Mac OS and Linux.
Node.js comprises a library of diverse JavaScript modules, which can be loaded via a simple function call and can be used as ready-made building blocks for developing web applications. One example is the HTTP module, which can create a rudimentary web server with a single function. Additionally, the integrated node package manager (NPM) can be used to install further modules.
One great advantage of Node.js is the event-driven architecture, which allows program code to be executed asynchronously. As Node.js is based on single threading and a non-blocking input/output system (I/O) it allows parallel processing of several read and write operations.
The development for this cross-platform software project was started by Ryan Dahl in 2009 and it is based on Google’s JavaScript Engine V8, which is also used in the Chrome web browser. Launched by the company, Joyent, the project has been run since 2015 by the Node.js Foundation, a Linux Foundation project. Current versions are available for Microsoft Windows, Mac OS and Linux.
Node.js comprises a library of diverse JavaScript modules, which can be loaded via a simple function call and can be used as ready-made building blocks for developing web applications. One example is the HTTP module, which can create a rudimentary web server with a single function. Additionally, the integrated node package manager (NPM) can be used to install further modules.
One great advantage of Node.js is the event-driven architecture, which allows program code to be executed asynchronously. As Node.js is based on single threading and a non-blocking input/output system (I/O) it allows parallel processing of several read and write operations.
- Asynchronous I/O: some of the most common tasks for servers include answering queries, storing data in a database, reading files from the hard drive, and establishing connections to other network components. These actions can be grouped together under the category ‘I/O’ (input/output). In programming languages like C and Java, I/O operations are executed synchronously. This means that tasks are performed one at a time and the I/O system is blocked until the current task has been completed. Node.js, however, uses an asynchronous I/O, with which read and write operations can be delegated directly to the operating system or a database. This makes it possible for a large number of I/O tasks to be carried out parallel to one another, without leading to a blockage. In some cases, this can prove to be a great advantage when it comes to the speed of the Node.js and JavaScript-based applications.
- Single-Threading: in order to compensate for the synchronous I/O waiting times, server applications written in traditional programming languages use additional threads with the above-mentioned disadvantages of a multithreading approach. An Apache HTTP server, for example, starts a new thread for every incoming query. The available memory limits the number of possible threads and therefore also the number of queries that can be answered in parallel in a synchronous multithreading system. However, because of its non-blocking I/O system, Node.js works with just one thread, which significantly reduces both the complexity as well as the resource load.
- Event-driven architecture: the asynchronous processing of I/O operations is realized through Node.js’s event-driven architecture. This is primarily based on an individual thread, located in a continually running event loop. This event loop has the task of waiting for events and then managing them. Events can exist as either tasks or results. If the event loop registers a task, such as a database query, this will be outsourced to a process in the background via a callback function. For this reason the task is not processed in the thread the event loop runs in, so that the loop can immediately go to the next event. If an outsourced task is being carried out, the results of the outsourced process will be returned to the event loop as a new event via the callback function. As a result, this can prompt the delivery of a result.
You might also find our article on "Deno: A runtime environment for JavaScript and TypeScript" interesting.
Installation
Node.js is available to download as a binary package or installer from the official Node.js website. In addition, the Node.js Foundation has also made the software’s source code and binary packages for ARM and SunOS, as well as a Docker available. For example, in order to install Node.js on a Windows PC, users just need to download the Windows installer, either in the 32-bit or 64-bit version. As well as the current version, 7.0.0, the long-term support (LTS release) 6.9.1 is available, which this Node.js tutorial is based on. The installation setup wizard is opened by double-clicking on the .msi file. Users must then click through the licensing terms, accept them, and choose the installation path and the components that are to be installed. Users can check to see if the installation was successful by starting Node.js and carrying out the first, simple JavaScript code. This can be done with the console.log() function, which allows users to output values in the Node.js console. The following line of code is a standard example that can be found in many Node.js tutorials:
console.log('Hello world!');
When this is entered into the console and confirmed with the enter key, the Node.js function prompts users to wrote the words, ‘Hello world!” into the console.
This simple example indicates that Node.js is functioning properly and JavaScript code can be executed. Alternatively, console.log() can be used to output the results of an arithmetic problem into the console:
console.log (15 + 385 * 20);
If you would like more detailed information about your version of Node.js and its modules, you can enter the following command into the Node.js console:
process.versions
Node.js modules
Node.js allows users to create efficient web servers and other network applications in the popular script language, JavaScript, and offers an extensive library of program modules for this purpose. These basic modules, which are integrated into the run time environment, comprise core functions such as the interaction with the operating system, the network communication, or encryption mechanisms. With the integrated package manager NPM, Node.js offers the option of installing individual program modules later.
Basic modules
To load any basic module in a Node.js application, you just need to use the require() function. This brings up a string that repots as a parameter, which module should be loaded. If this is one of the basic modules, the module name is sufficient. For modules that have been installed later on, the string must include the module path, even if the module is in the current directory (in this case, the path is simply ‘./’). The following lines of code indicate the basic schema for loading modules in the Node.js applications:
var module name = require('path/modulename');
If the basic module, ‘os’ is to be loaded, for example, the code should look like this:
var os = require('os');
The module, ‘os’, offers diverse functions that can be used to output information relating to the operating system. If a user wants to find out the amount of free memory in bytes, for example, the following code can be used:
var os = require('os');
var freemem = os.freemem();
console.log(freemem);
In the first line the module, ‘os’ is loaded in the variable of the same name, ‘os’. The segment of code, os.freemem() in line 2 is one of the functions supported by the module ‘os’, and is used determine the amount of free memory in bytes. The resulting value is saved in the variable, freemem. Finally, in the third line, the function console.log() is used to write the value saved in the variable freemem into the console.
As shown in the Node.js console window, 5 gigabytes of memory are currently available.
With the ‘os’ module’s other functions, such as os.networkInterfaces() or os.hostname(), a list of all the network interfaces can be output or hostnames can be determined. Further information about the functions of the ‘os’ module and Node.js’s other basic modules can be found in its official documentation.
With the ‘os’ module’s other functions, such as os.networkInterfaces() or os.hostname(), a list of all the network interfaces can be output or hostnames can be determined. Further information about the functions of the ‘os’ module and Node.js’s other basic modules can be found in its official documentation.
Installing modules
With the integrated package manager, NPM, users can install more program modules later on. Extension modules don’t have to be downloaded manually from external pages and copied into an appropriate directory. This means the effort involved in the installation process is reduced to a single line of code, which is entered into the console of the operating system (not in the Node.js console!). With Windows operating systems, this is the command line interpreter cmd.exe, which can be accessed through entering this as a command into the Windows run dialog (Windows key + R). All that’s needed is the command npm install and the name of the module to be installed:
npm install module name
All available additional modules for Node.js can be found via the search function on the official NPM website. If, for example, the program module ‘colors’ is to be installed, users should navigate to the appropriate directory in the operating system’s console and confirm the following command with the enter key:
npm install colors
This screenshot shows the installation of the color module in the folder C:\MyModules:
The function require() can be used in order to load the newly installed module in an application. The following example of code shows how the color module is implemented in order to highlight entries in the Node.js console different colors:
var colors = require('C:/MyModules/node_modules/colors');
console.log('hello'.green); // makes text green
console.log('I like cake and pies'.bold.red) // makes text red and bold
console.log('inverse the color'.inverse); // inverts colors
console.log('All work and no play makes Jack a dull boy!'.rainbow); // rainbow text
In the first line of code the module ‘colors’ is loaded in the variable of the same name, colors, with the path C:/MyModules/node_modules/colors. The lines 2 to 5 each include a function console.log(), the strings of which are highlighted in different ways by the color module. It’s possible to use various commands to adjust the colors (i.e. .red, .green), highlight (i.e. .bold, .inverse), and create sequences (i.e. .rainbow).
Case study: creating a web server with eight lines of code
Developing a lightweight web server is one of the standard applications of Node.js. Thanks to the included ‘http’ module, a simple ‘Hello world!’ server can be programmed within seconds. All you need to implement this is the following eight lines of JavaScript code, which can be created in a text editor and saved as a JavaScript file in any folder. In this Node.js tutorial, the file is name webserver.js and saved in the file MyWebServer.
var http = require('http');
var port = 8080;
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello world!');
});
server.listen(port);
console.log('The server is available at http://127.0.0.1:' + port + '/');
In the first line of code the web server module ‘http’ is loaded via the function, require(), and saved in the variable http.
var http = require('http');
In the second line, the port number 8080 is defined and saved in the variable, port.
var port = 8080;
Using the http module’s function, createServer(), the lines 3 to 6 define a callback function, which receive incoming browser requests (req) and return a response (res). The response to the browser consists of the header containing the HTTP status code 200 (OK), as well as the information that the rest of the response is a text. This is then inserted via the res.end() function. The content of the answer: ‘Hello, world!’
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hallo Welt!');
});
Code line 7 is used to connect the web server with the listen() function in the port number defined in like 2.
server.listen(port);
The final code line, 8, gives the web address under which the web server can be found in the console.
console.log('The server is available at http://127.0.0.1:' + port + '/');
127.0.0.1 is the localhost address. The web server is thus only available within the system. In order to start it, run the JavaScript file you just created with the operating system’s console. This is done with a command like this:
node path/script.js
In this example, the command is as follows:
node C:\MyWebServer\webserver.js
In this example, we work with the Windows console which uses backslashes instead of slashes in the file path. If the script is copied without errors and the file path specified correctly, the console displays the server’s web address:
The web server is now ready to accept requests. You can test this by entering the web address 127.0.01:8080 in any web browser. If the server has been programmed correctly, the browser window will display the words, ‘Hello, world!’