Node.js is an event-based, non-blocking, asynchronous I/O framework that uses Google's V8 JavaScript engine. It is used for developing applications that make heavy use of the ability to run JavaScript both on the client, as well as on server side and therefore benefit from the re-usability of code and the lack of context switching. It is open-source and cross-platform. Node.js applications are written in pure JavaScript and can be run within Node.js environment on Windows, Linux etc…
Version | Release Date |
---|---|
v8.2.1 | 2017-07-20 |
v8.2.0 | 2017-07-19 |
v8.1.4 | 2017-07-11 |
v8.1.3 | 2017-06-29 |
v8.1.2 | 2017-06-15 |
v8.1.1 | 2017-06-13 |
v8.1.0 | 2017-06-08 |
v8.0.0 | 2017-05-30 |
v7.10.0 | 2017-05-02 |
v7.9.0 | 2017-04-11 |
v7.8.0 | 2017-03-29 |
v7.7.4 | 2017-03-21 |
v7.7.3 | 2017-03-14 |
v7.7.2 | 2017-03-08 |
v7.7.1 | 2017-03-02 |
v7.7.0 | 2017-02-28 |
v7.6.0 | 2017-02-21 |
v7.5.0 | 2017-01-31 |
v7.4.0 | 2017-01-04 |
v7.3.0 | 2016-12-20 |
v7.2.1 | 2016-12-06 |
v7.2.0 | 2016-11-22 |
v7.1.0 | 2016-11-08 |
v7.0.0 | 2016-10-25 |
v6.11.0 | 2017-06-06 |
v6.10.3 | 2017-05-02 |
v6.10.2 | 2017-04-04 |
v6.10.1 | 2017-03-21 |
v6.10.0 | 2017-02-21 |
v6.9.5 | 2017-01-31 |
v6.9.4 | 2017-01-05 |
v6.9.3 | 2017-01-05 |
v6.9.2 | 2016-12-06 |
v6.9.1 | 2016-10-19 |
v6.9.0 | 2016-10-18 |
v6.8.1 | 2016-10-14 |
v6.8.0 | 2016-10-12 |
v6.7.0 | 2016-09-27 |
v6.6.0 | 2016-09-14 |
v6.5.0 | 2016-08-26 |
v6.4.0 | 2016-08-12 |
v6.3.1 | 2016-07-21 |
v6.3.0 | 2016-07-06 |
v6.2.2 | 2016-06-16 |
v6.2.1 | 2016-06-02 |
v6.2.0 | 2016-05-17 |
v6.1.0 | 2016-05-05 |
v6.0.0 | 2016-04-26 |
v5.12.0 | 2016-06-23 |
v5.11.1 | 2016-05-05 |
v5.11.0 | 2016-04-21 |
v5.10.1 | 2016-04-05 |
v5.10 | 2016-04-01 |
v5.9 | 2016-03-16 |
v5.8 | 2016-03-09 |
v5.7 | 2016-02-23 |
v5.6 | 2016-02-09 |
v5.5 | 2016-01-21 |
v5.4 | 2016-01-06 |
v5.3 | 2015-12-15 |
v5.2 | 2015-12-09 |
v5.1 | 2015-11-17 |
v5.0 | 2015-10-29 |
v4.4 | 2016-03-08 |
v4.3 | 2016-02-09 |
v4.2 | 2015-10-12 |
v4.1 | 2015-09-17 |
v4.0 | 2015-09-08 |
io.js v3.3 | 2015-09-02 |
io.js v3.2 | 2015-08-25 |
io.js v3.1 | 2015-08-19 |
io.js v3.0 | 2015-08-04 |
io.js v2.5 | 2015-07-28 |
io.js v2.4 | 2015-07-17 |
io.js v2.3 | 2015-06-13 |
io.js v2.2 | 2015-06-01 |
io.js v2.1 | 2015-05-24 |
io.js v2.0 | 2015-05-04 |
io.js v1.8 | 2015-04-21 |
io.js v1.7 | 2015-04-17 |
io.js v1.6 | 2015-03-20 |
io.js v1.5 | 2015-03-06 |
io.js v1.4 | 2015-02-27 |
io.js v1.3 | 2015-02-20 |
io.js v1.2 | 2015-02-11 |
io.js v1.1 | 2015-02-03 |
io.js v1.0 | 2015-01-14 |
v0.12 | 2016-02-09 |
v0.11 | 2013-03-28 |
v0.10 | 2013-03-11 |
v0.9 | 2012-07-20 |
v0.8 | 2012-06-22 |
v0.7 | 2012-01-17 |
v0.6 | 2011-11-04 |
v0.5 | 2011-08-26 |
v0.4 | 2011-08-26 |
v0.3 | 2011-08-26 |
v0.2 | 2011-08-26 |
v0.1 | 2011-08-26 |
First, install Node.js for your platform.
In this example we'll create an HTTP server listening on port 1337, which sends Hello, World!
to the browser. Note that, instead of using port 1337, you can use any port number of your choice which is currently not in use by any other service.
The http
module is a Node.js core module (a module included in Node.js's source, that does not require installing additional resources). The http
module provides the functionality to create an HTTP server using the http.createServer()
method.
To create the application, create a file containing the
following JavaScript code.
const http = require('http'); // Loads the http module
http.createServer((request, response) => {
// 1. Tell the browser everything is OK (Status code 200), and the data is in plain text
response.writeHead(200, {
'Content-Type': 'text/plain'
});
// 2. Write the announced text to the body of the page
response.write('Hello, World!\n');
// 3. Tell the server that all of the response headers and body have been sent
response.end();
}).listen(1337); // 4. Tells the server what port to be on
Save the file with any file name. In this case, if we name it hello.js
we can run the application by going to the directory the file is in and using the following command:
node hello.js
The created server can then be accessed with the URL http://localhost:1337 or http://127.0.0.1:1337 in the browser.
A simple web page will appear with a “Hello, World!” text at the top, as shown in the screenshot below.
Node.js is a Javascript engine (Google's V8 engine for Chrome, written in C++) that allows to run Javascript outside the browser. While numerous libraries are available for extending Node's functionalities, the engine comes with a set of core modules implementing basic functionalities.
There's currently 34 core modules included in Node:
[ 'assert',
'buffer',
'c/c++_addons',
'child_process',
'cluster',
'console',
'crypto',
'deprecated_apis',
'dns',
'domain',
'Events',
'fs',
'http',
'https',
'module',
'net',
'os',
'path',
'punycode',
'querystring',
'readline',
'repl',
'stream',
'string_decoder',
'timers',
'tls_(ssl)',
'tracing',
'tty',
'dgram',
'url',
'util',
'v8',
'vm',
'zlib' ]
This list was obtained from the Node documentation API https://nodejs.org/api/all.html (JSON file: https://nodejs.org/api/all.json).
assert
The assert
module provides a simple set of assertion tests that can be used to
test invariants.
buffer
Prior to the introduction of TypedArray
in ECMAScript 2015 (ES6), the
JavaScript language had no mechanism for reading or manipulating streams
of binary data. The Buffer
class was introduced as part of the Node.js
API to make it possible to interact with octet streams in the context of things
like TCP streams and file system operations.
Now that TypedArray
has been added in ES6, the Buffer
class implements the
Uin
t8Array
API in a manner that is more optimized and suitable for Node.js'
use cases.
c/c++_addons
Node.js Addons are dynamically-linked shared objects, written in C or C++, that
can be loaded into Node.js using the require()
function
, and used
just as if they were an ordinary Node.js module. They are used primarily to
provide an interface between JavaScript running in Node.js and C/C++ libraries.
child_process
The child_process
module provides the ability to spawn child processes in
a manner that is similar, but not identical, to popen(3).
A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load. The cluster module allows you to easily create child processes that all share server ports.
console
The console
module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
crypto
The crypto
module provides cryptographic functionality that includes a set of
wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign and verify functions.
deprecated_apis
Node.js may deprecate APIs when either: (a) use of the API is considered to be unsafe, (b) an improved alternative API has been made available, or (c) breaking changes to the API are expected in a future major release.
dns
The dns
module contains functions belonging to two different categories:
dns.lookup()
.dns
module except dns.lookup()
.domain
This module is pending deprecation. Once a replacement API has been finalized, this module will be fully deprecated. Most end users should not have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.
Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") periodically emit named events that cause Function objects ("listeners") to be called.
fs
File I/O is provided by simple wrappers around standard POSIX functions. To use this module do require('fs')
. All the methods have asynchronous and synchronous forms.
The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possibly chunk-encoded, messages. The interface is careful to never buffer entire requests or responses--the user is able to stream data.
https
HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module.
module
Node.js has a simple module loading system. In Node.js, files and modules are in one-to-one correspondence (each file is treated as a separate module).
net
The net
module provides you with an asynchronous network wrapper. It contains
functions for creating both servers and clients (called streams). You can include
this module with require('net');
.
os
The os
module provides a number of operating system-related utility methods.
path
The path
module provides utilities for working with file and directory paths.
punycode
The version of the punycode module bundled in Node.js is being deprecated.
querystring
The querystring
module provides utilities for parsing and formatting URL query strings.
The readline
module provides an interface for reading data from a Readable
stream (such as process.stdin
) one line at a time.
repl
The repl
module provides a Read-Eval-Print-Loop (REPL) implementation that
is available both as a standalone program or includible in other applications.
A stream is an abstract interface for working with streaming data in Node.js.
The stream
module provides a base API that makes it easy to build objects
that implement the stream interface.
There are many stream objects provided by Node.js. For instance, a
request to an HTTP server and process.stdout
are both stream instances.
string_decoder
The string_decoder
module provides an API for decoding Buffer
objects into
strings in a manner that preserves encoded multi-byte UTF-8 and UTF-16
characters.
timers
The timer
module exposes a global API for scheduling functions to
be called at some future period of time. Because the timer functions are
globals, there is no need to call require('timers')
to use the API.
The timer functions within Node.js implement a similar API as the timers API provided by Web Browsers but use a different internal implementation that is built around the Node.js Event Loop.
tls_(ssl)
The tls
module provides an implementation of the Transport Layer Security
(TLS) and Secure Socket Layer (SSL) protocols that is built on top of OpenSSL.
tracing
Trace Event provides a mechanism to centralize tracing information generated by V8, Node core, and userspace code.
Tracing can be enabled by passing the --trace-events-enabled
flag when starting a
Node.js application.
tty
The tty
module provides the tty.ReadStream
and tty.WriteStream
classes.
In most cases, it will not be necessary or possible to use this module directly.
dgram
The dgram
module provides an implementation of UDP Datagram sockets.
url
The url
module provides utilities for URL resolution and parsing.
util
The util
module is primarily designed to support the needs of Node.js' own internal APIs. However, many of the utilities are useful for application and module developers as well.
v8
The v8
module exposes APIs that are specific to the version of V8 built into the Node.js binary.
Note: The APIs and implementation are subject to change at any time.
vm
The vm
module provides APIs for compiling and running code within V8 Virtual Machine contexts.
JavaScript code can be compiled and run immediately or compiled, saved, and run
later.
Note: The vm module is not a security mechanism. Do not use it to run untrusted code.
zlib
The zlib
module provides compression functionality implemented using Gzip and
Deflate/Inflate.
You can use the node-inspector. Run this command to install it via npm:
npm install -g node-inspector
Then you can debug your application using
node-debug app.js
The Github repository can be found here: https://github.com/node-inspector/node-inspector
You can also debug node.js natively by starting it like this:
node debug your-script.js
To breakpoint your debugger exactly in a code line you want, use this:
debugger;
For more information see here.
In node.js 8 use the following command:
node --inspect-brk your-script.js
Then open about://inspect
in a recent version of Google Chrome and select your Node script to get the debugging experience of Chrome's DevTools.
When you deploy your app to a (Node.js-specific) hosted environment, this environment usually offers a PORT
-environment variable that you can use to run your server on. Changing the port number to process.env.PORT
allows you to access the application.
For example,
http.createServer(function(request, response) {
// your server code
}).listen(process.env.PORT);
Also, if you would like to access this offline while debugging, you can use this:
http.createServer(function(request, response) {
// your server code
}).listen(process.env.PORT || 3000);
where 3000
is the offline port number.
Once you understand how to create an HTTP Server with node, it's important to understand how to make it "do" things based on the path that a user has navigated to. This phenomenon is called, "routing".
The most basic example of this would be to check if (request.url === 'some/path/here')
, and then call a function that responds with a new file.
An example of this can be seen here:
const http = require('http');
function index (request, response) {
response.writeHead(200);
response.end('Hello, World!');
}
http.createServer(function (request, response) {
if (request.url === '/') {
return index(request, response);
}
response.writeHead(404);
response.end(http.STATUS_CODES[404]);
}).listen(1337);
If you continue to define your "routes" like this, though, you'll end up with one massive callback function, and we don't want a giant mess like that, so let's see if we can clean this up.
First, let's store all of our routes in an object:
var routes = {
'/': function index (request, response) {
response.writeHead(200);
response.end('Hello, World!');
},
'/foo': function foo (request, response) {
response.writeHead(200);
response.end('You are now viewing "foo"');
}
}
Now that we've stored 2 routes in an object, we can now check for them in our main callback:
http.createServer(function (request, response) {
if (request.url in routes) {
return routes[request.url](request, response);
}
response.writeHead(404);
response.end(http.STATUS_CODES[404]);
}).listen(1337);
Now every time you try to navigate your website, it will check for the existence of that path in your routes, and it will call the respective function. If no route is found, the server will respond with a 404 (Not Found).
And there you have it--routing with the HTTP Server API is very simple.
Node.js can also be used to create command line utilities. The example below reads the first argument from the command line and prints a Hello message.
To run this code on an Unix System:
chmod 700 FILE_NAME
./APP_NAME David
On Windows you do step 1 and run it with node APP_NAME David
#!/usr/bin/env node
'use strict';
/*
The command line arguments are stored in the `process.argv` array,
which has the following structure:
[0] The path of the executable that started the Node.js process
[1] The path to this application
[2-n] the command line arguments
Example: [ '/bin/node', '/path/to/yourscript', 'arg1', 'arg2', ... ]
src: https://nodejs.org/api/process.html#process_process_argv
*/
// Store the first argument as username.
var username = process.argv[2];
// Check if the username hasn't been provided.
if (!username) {
// Extract the filename
var appName = process.argv[1].split(require('path').sep).pop();
// Give the user an example on how to use the app.
console.error('Missing argument! Example: %s YOUR_NAME', appName);
// Exit the app (success: 0, error: 1).
// An error will stop the execution chain. For example:
// ./app.js && ls -> won't execute ls
// ./app.js David && ls -> will execute ls
process.exit(1);
}
// Print the message to the console.
console.log('Hello %s!', username);
When called without arguments, Node.js starts a REPL (Read-Eval-Print-Loop) also known as the “Node shell”.
At a command prompt type node
.
$ node
>
At the Node shell prompt >
type "Hello World!"
$ node
> "Hello World!"
'Hello World!'
The following example uses Express to create an HTTP server listening on port 3000, which responds with "Hello, World!". Express is a commonly-used web framework that is useful for creating HTTP APIs.
First, create a new folder, e.g. myApp
. Go into myApp
and make a new JavaScript file containing the following code (let's name it hello.js
for example). Then install the express module using npm install --save express
from the command line. Refer to this documentation for more information on how to install packages.
// Import the top-level function of express
const express = require('express');
// Creates an Express application using the top-level function
const app = express();
// Define port number as 3000
const port = 3000;
// Routes HTTP GET requests to the specified path "/" with the specified callback function
app.get('/', function(request, response) {
response.send('Hello, World!');
});
// Make the app listen on port 3000
app.listen(port, function() {
console.log('Server listening on http://localhost:' + port);
});
From the command line, run the following command:
node hello.js
Open your browser and navigate to http://localhost:3000
or http://127.0.0.1:3000
to see the response.
For more information about the Express framework, you can check the Web Apps With Express section
Once you have node.js installed on your system, you can just follow the procedure below to get a basic web server running with support for both HTTP and HTTPS!
create the folder where you want to store your key & certificate :
mkdir conf
go to that directory :
cd conf
grab this ca.cnf
file to use as a configuration shortcut :
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
create a new certificate authority using this configuration :
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
now that we have our certificate authority in ca-key.pem
and ca-cert.pem
, let's generate a private key for the server :
openssl genrsa -out key.pem 4096
grab this server.cnf
file to use as a configuration shortcut :
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
generate the certificate signing request using this configuration :
openssl req -new -config server.cnf -key key.pem -out csr.pem
sign the request :
openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
copy your certificate to your root certificates' folder :
sudo cp ca-crt.pem /usr/local/share/ca-certificates/ca-crt.pem
update CA store :
sudo update-ca-certificates
First, you want to create a server.js
file that contains your actual server code.
The minimal setup for an HTTPS server in Node.js would be something like this :
var https = require('https');
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
https.createServer(httpsOptions, app).listen(4433);
If you also want to support http requests, you need to make just this small modification :
var http = require('http');
var https = require('https');
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);
go to the directory where your server.js
is located :
cd /path/to
run server.js
:
node server.js
To begin, install Node.js on your development computer.
Windows: Navigate to the download page and download/run the installer.
Mac: Navigate to the download page and download/run the installer. Alternatively, you can install Node via Homebrew using brew install node
. Homebrew is a command-line package mananger for Macintosh, and more information about it can be found on the Homebrew website.
Linux: Follow the instructions for your distro on the command line installation page.
To run a Node.js program, simply run node app.js
or nodejs app.js
, where app.js
is the filename of your node app source code. You do not need to include the .js
suffix for Node to find the script you'd like to run.
Alternatively under UNIX-based operating systems, a Node program may be executed as a terminal script. To do so, it needs to begin with a shebang pointing to the Node interpreter, such as #!/usr/bin/env node
. The file also has to be set as executable, which can be done using chmod
. Now the script can be directly run from the command line.
The only major differences between this and a regular TCP connection are the private Key and the public certificate that you’ll have to set into an option object.
The first step in this security process is the creation of a private Key. And what is this private key? Basically, it's a set of random noise that's used to encrypt information. In theory, you could create one key, and use it to encrypt whatever you want. But it is best practice to have different keys for specific things. Because if someone steals your private key, it's similar to having someone steal your house keys. Imagine if you used the same key to lock your car, garage, office, etc.
openssl genrsa -out private-key.pem 1024
Once we have our private key, we can create a CSR (certificate signing request), which is our request to have the private key signed by a fancy authority. That is why you have to input information related to your company. This information will be seen by the signing authority, and used to verify you. In our case, it doesn’t matter what you type, since in the next step we're going to sign our certificate ourselves.
openssl req -new -key private-key.pem -out csr.pem
Now that we have our paper work filled out, it's time to pretend that we're a cool signing authority.
openssl x509 -req -in csr.pem -signkey private-key.pem -out public-cert.pem
Now that you have the private key and the public cert, you can establish a secure connection between two NodeJS apps. And, as you can see in the example code, it is a very simple process.
Since we created the public cert ourselves, in all honesty, our certificate is worthless, because we are nobodies. The NodeJS server won't trust such a certificate by default, and that is why we need to tell it to actually trust our cert with the following option rejectUnauthorized: false. Very important: never set this variable to true in a production environment.
'use strict';
var tls = require('tls');
var fs = require('fs');
const PORT = 1337;
const HOST = '127.0.0.1'
var options = {
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('public-cert.pem')
};
var server = tls.createServer(options, function(socket) {
// Send a friendly message
socket.write("I am the server sending you a message.");
// Print the data that we received
socket.on('data', function(data) {
console.log('Received: %s [it is %d bytes long]',
data.toString().replace(/(\n)/gm,""),
data.length);
});
// Let us know when the transmission is over
socket.on('end', function() {
console.log('EOT (End Of Transmission)');
});
});
// Start listening on a specific port and address
server.listen(PORT, HOST, function() {
console.log("I'm listening at %s, on port %s", HOST, PORT);
});
// When an error occurs, show it.
server.on('error', function(error) {
console.error(error);
// Close the connection after the error occurred.
server.destroy();
});
'use strict';
var tls = require('tls');
var fs = require('fs');
const PORT = 1337;
const HOST = '127.0.0.1'
// Pass the certs to the server and let it know to process even unauthorized certs.
var options = {
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('public-cert.pem'),
rejectUnauthorized: false
};
var client = tls.connect(PORT, HOST, options, function() {
// Check if the authorization worked
if (client.authorized) {
console.log("Connection authorized by a Certificate Authority.");
} else {
console.log("Connection not authorized: " + client.authorizationError)
}
// Send a friendly message
client.write("I am the client sending you a message.");
});
client.on("data", function(data) {
console.log('Received: %s [it is %d bytes long]',
data.toString().replace(/(\n)/gm,""),
data.length);
// Close the connection after receiving the message
client.end();
});
client.on('close', function() {
console.log("Connection closed");
});
// When an error ocoures, show it.
client.on('error', function(error) {
console.error(error);
// Close the connection after the error occurred.
client.destroy();
});