JavaScript meets back-end server hosting

Tuesday, Feb 4, 2020


Node.js provides server-side functionality in familiar Javascript syntax and an asynchronous model. To be clear, Node.js is not a programming language. It adds features to Javascript that allow developers to write server-side code in familiar front-end language.

How It Works

As an interpreted language (like Python), Javascript requires a runtime engine to be run. How Node js functions as a server side language is its runtime engine allows it to interact with a server. In the browser, a Javascript engine provides access to Web Platform APIs and the window HTML (DOM). Node uses Google’s V8 Javascript engine instead to access files, send data, and provide other server capabilities. The V8 engine powers Chrome, but there are other engines out there:

  1. Firefox uses SpiderMonkey
  2. Safari uses JavaScriptCore
  3. IE uses who on 🌍 cares

Let me explain in a simple diagram:

   +-------------+               +---------------+
   |   BROWSER   |               |    SERVER     |
   |  Client JS  |               |    Node JS    |
   |-------------|               |---------------|
   |    Other    |               | V8 JS Engine  |
   |  JS Engine  |               |     (C++)     |
   +------+-+----+               +-------+--+----+
          | ^                            |  ^
          | |                            |  |
          | |                            |  |
          | +----+----------------+<-----+  |
          |      |   WEB SERVER   |         |
          +----> +----------------+---------+

The Chrome V8 Javascript engine provides C++ bindings for Javascript. The V8 Engine then passes events and data between the server and client.

Let’s take a small example. Javascript has no concept of accessing system files, but in Node.js, we gain this functionality through modules. We’ll get to modules later, but here’s a small example of what you can do with Node.js using the built in filesystem module fs.

Create the following file, helloworld.js:

const fs = require("fs")
console.log(fs.writeFileSync("", "**Hello World!** Bet your browser JS can't do this!"))

Then in the console, run the file by typing $ node helloworld.js. This will create the file with the text: Hello World! Bet your browser JS can't do this!.

Alternatively, you can run this in the node console. In your terminal, typing node creates a shell utilizing a REPL:

What this means is that as expressions are evaluated, their return value is printed in the console. You can invoke the REPL by just typing node in your terminal. Then, you can test what expressions are doing. Which is useful for debugging expressions and playing around with Javascript.

$ node
> a = 3
> ++_

Warning: In this example, we used _ , which refers to the previous expression. However, this feature has been deprecated, and you’ll get an annoying warning if you try to use it.

You’ll notice that the return value is printed below each statement executed.

> v = "Vim"
> e = "Emacs"
> console.log("I'm a pro since I use ", v)
I'm a pro since I use Vim

In the next example, we’ll use dictionary and list data structures:

> listOfEditors = [v, e]
[ 'Vim', 'Emacs' ]
> editors = {}
> editors[v] = "superior"
> editors[e] = "inferior"
> editors
{ Vim: 'superior', Emacs: 'inferior }

You can exit the REPL by pressing ^D or ^C^C.

The process variable, only accessible to you in Node, not in the browser. process is a list of current tasks that Node is executing. Typing process in the REPL will dump a huge list and process.exit() command also exits the REPL.

$ node
> process

Module System

Modules in Nodejs are essentially Javascript libraries. There are quite a few built-in libraries available by default in Nodejs, including (thanks to W3 Schools for the rundown):

How to Import and Use a Module:

To use a module, you simply require using the format:

require('<module name>')

For example, to import and use the file system module fs just like we did above:

const fs = require('fs')
fs.writeFileSync('helloNode.txt', '**That was easy!**™️🤓')

It’s Nodejs convention to use the module name for variable used to call its functions.

How to Import Your Own Modules

Importing Modules

To import and use code you wrote in another file, use the require() function, passing in the parameter of the filepath

The Core

Nodejs requires a few critical components that allow it to provide its functionality. These components are:

  1. the Global objects
  2. Timer methods
  3. Socket and Stream functionality
  4. the Utilities object
  5. Events

These objects are also what separate Nodejs applications from vanilla Javascript code.

Global objects

There are three primary global objects available in Nodejs. They are:

  1. global
  2. process
  3. Buffer

Each of these objects are in a Node application’s namespace, meaning a require statement is not required (bad pun intended).

Variables and required objects are accessible within the application’s namespace. This access is restricted to the variables within the application, meaning you are unable to change the value of variables in other other modules. This prevents accidental collisions when code from another module runs.

The process object provides access to the Node installation, the three methods of standard I/O (stdin, stderr, stdout), and application memory usage.

The Buffer object handles binary data. You can read any type of data through a buffer, including a file, input stream, or network connection. A Buffer object take up to two parameters:

Buffer(<input-data>, <encoding>)


Timers in Nodejs allow programmers to delay and schedule execution of functions. The timer module includes the functions:

Sockets and Streams

There are four major types of streamed connections in Nodejs:

  1. TCP - net module
  2. HTTP - http module
  3. UDP/Datagram Socket - dgram module
  4. Readline/Child_Process - readline, child_process modules

Using a TCP connection, we can recieve messages from client’s standard input on the server program. The process is used directly here to access standard I/O streams.

For example:

Working with I/O

The .pipe(<stream>) is used to send the ouput of one stream to another.

Reading streams with readline

The readline module allows the reading of standard I/O streams line by line during program execution. When the programmer is done reading a stream, they must be closed. The REPL is implemented by piping your terminal input stdin, executing Javascript commands and piping stdout back to your terminal.

Using system streams with child_process

Using the child_process module, a Node application can make system calls and recieve input from standard I/O. We do this in Node by defining a child process and redirecting its input and output by defining functions for whenever specific input is recieved.

For example, let’s take the command ls:

You can specify how the function interacts with I/O by using the .on() method

Specifying how ls() interacts with stdin, stdout, and stderr:

ls.stdout.on('data', (data) => {
  console.log(`The output of ls is ${data}`)

ls.stderr.on('data', (data) => {
  console.log(`ls exited with error ${data}`)

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);

The program below illustrates an elaborate way to execute the command: ls | grep "fork"


The utilities object enables inheritance in Node. An object can be inherited by another object using the inherits function:

util.inherits(<source-object>, <target-object>)

Events & EventEmitter

As mentioned previously, event based programming is fundamental to the Node philosophy. The events module allows programmers to define actions for events much like try/catch blocks in Java and C++ or try/except blocks in Python. This method of programming puts the programmer in an event driven mindset to focus on all the events that a program must handle. Node modules are written to minimize the amount of boilerplate code written and shift focus to the actions.

Here are the steps to define an event:

  1. require: require('events')
  2. instantiate
  3. define the callback
  4. define the event


Data Types

JavaScript has primitive data types, which are immutable

  1. Number
  2. String
  3. Boolean
  4. Null
  5. Undefined
  6. Symbol

JavaScript also has some built-in objects

  1. Array
  2. Date
  3. RegExp
  4. Map & WeakMap
  5. Set & WeakSet

Specifying Integer Type

Number Properties

Special Characters

Code Description
\n newline
\r carriage return
\t horizontal tab
\' single quote
\$ dollar sign
\\ back-slash
\b backspace
\f form feed
\v vertical tab
&grave; grave symbol

String Substitutions

const temp = 22.5
console.log(`The value is ${temp}`)

null and undefined



A variable can be defined using normal letters, as well as UTF-8 characters

Arrow Functions

Arrow functions allow us to give a function an identifier.

// After this has been written, we can now call the identifier and give it input
const squareIt = (x) => x * x

squareIt(10) // '100'

Equality ‘==’ vs. ‘===’

The identity operator === will compare both types and values between two variables. JavaScript objects are compared by reference, not by value. An object is equal to itself, but not equal to a different object with the same value.

Some edge cases worth noting:

the “in” operator

The in operator evaluates to true if the left-side value is the name of a property of the right-side object

const data = [7, 8, 9]
"0" in data // true: array has an element "0"
1 in data // true: numbers are converted into strings
7 in data // false: no 7th element in this array

GitHub Package Registry

Add the following two lines to your ~/.npmrc

registry =

Add the read:packages and write:packages permissions to your GITHUB_TOKEN environment variable in the GitHub tokens page

Install a Package

To add this Package registered on the GitHub NPM Registry, enter the following command

npm install @codertocat/hello-world-npm

Alternatively, you can add the package as a dependency to the project’s package.json

  "name": "testjs",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@codertocat/hello-world-npm": "^1.0.2"

Publish a Package

Add the following to your package’s package.json

  "publishConfig": {