Node.js and Heroku

Let's learn how to use javascript to program a server based on Node.js and upload it so everyone can access our page. We will set it up so visitors can access several pages and perform several actions. You are expected to know javascript, including some ES6 for this lesson.

While the tools and libraries change from project to project, the methodology is somewhat similar: Start, Develop, Test and Deploy. Most of these can be partially automated.

Start project

If you followed the "the Getting started lesson you should have Node.js and NPM installed in the system.

First create a folder for our project. I will be using one in the location ~/projects/web, but you can set it up wherever you prefer. Then you should access it from the terminal. For *nix systems (Mac & Linux):

cd ~/projects/web

This will make all the successive commands to execute for your project. So let's get the first one, initialize the project with NPM:

npm init

Then you can follow the questions to set up your project. The answers are not really important, so don't overthink them or just use the defaults. After this is finished, you should see a file called "package.json" within your folder.

Now we will install the library server to make development easier:

npm install server --save

The --save option is there so that Node.js knows that we depend on this library when deploying the code later on.

If you happen to find any error with a weird message you can just Google it. Fortunately Node.js is mature enough so any installation/start error can be solvable with some searching around.

Node.js code

This is a mandatory "Hello world" program. Create a file called "app.js":

// Include the library "server"
const server = require('server');

// Retrieve a router for browser calls (explained later)
const { get } = server.router;

// Launch the server listening for "GET /"
  get('/', ctx => ctx.res.send('Hello world'))

If you don't understand the previous don't worry, it will be explained later on. One of the main problems with Node.js is the steep learning curve which we try to minimize here.

Now we can see that message on the browser. Run it with nodemon (installed in the Getting started guide) and open http://localhost:3000/ in your browser

nodemon app.js

Nodemon automatically restarts Node.js each time your code changes so you don't need to do it manually.

Exercise: create a "Hello world" page in another language. "Hello world" is "Hola mundo" in Spanish and "こんにちは、世界" in Japanese.

Challenge: create a page that says "Bye world" when the browser opens "http://localhost:3000/bye".


Routing is the action of taking one request for a specific place and type and send it to the right place for processing.

First for this demo copy the files (index.html, style.css, javascript.js and any asset) into a new folder inside our project called "public". Then tell Node.js what files to display; let's display "public/index.html" by writing this in "app.js":

const server = require('server');
const { get, post } = server.router;

// Create the route "home" for the method "GET" in the url "/"
const home = get('/', ctx => ctx.res.sendFile(__dirname + '/public/index.html'));

// Launch the server with the route home

If we refresh http://localhost:3000/ we can see our index.html rendered. The server will automatically attempt to load other assets such as css and (front-end) javascript from the folder named "public".

Only the specific routes will be shown from now on for brevity, but you should write the whole code as shown before.

Now let's create a route to get the file requested dynamically. We will get the url fragment as the variable name and then use it:

// A router for any page such as "/contact", "/hello", etc
const page = get('/:name', ctx => {

  // This url part is stored here:

The previous one only shows us in the terminal what file we are reading and on the browser the file name. Let's actually display the file in the browser:

const page = get('/:name', ctx => {

  // Store the file name in a variable, defaulting to 'index.html'
  const name = || 'index';

  // We will need the full path to the file
  var file = __dirname + '/' + name + '.html';

  // Send this file to the browser


Let's try to create a form and handle it with Node.js. First we create the form in "public/contact.html":

<!DOCTYPE html>
    <title>Página Web</title>
    <meta charset="utf-8">
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <link rel="stylesheet" href="">
    <link rel="stylesheet" href="style.css">

    <form action="/contacto" method="POST" class="contact">
      <input name="name" placeholder="Nombre">
      <input name="lastname" placeholder="Apellidos">
      <input name="age" placeholder="Edad">
      <input type="submit" value="Enviar">


With some style touches in "public/style.css":

.contact {
  width: 500px;
  margin: 100px auto;

.contact input {
  margin-top: 0;
  margin-bottom: 10px;

Now we can read the data on the server. So far we won't be storing it, just display it on the terminal:

const printData = post('/contact', ctx => {

If everything worked fine, this should display our data from the contact form and then redirect us home. We could change this for a "/thankyou" page or just handle it with javascript on the front-end and not redirect anywhere.


A REST API is a group of URLs and actions that can be done to them (GET, POST, PUT, DELETE). Let's say we have a user system. This would be a basic REST API for it:

GET /users            # Get all of the users data
GET /users/456546     # Get one specific user data
POST /users           # Create a new user
PUT /users/435465     # Edit an existing user
DELETE /users         # Remove all the users
DELETE /users/354643  # Remove a single user

This is useful on its own, but specially useful with mobile apps as well as webapps (React, Angular, etc). It separates our logic at some specific points and makes it easier to handle the complexity.

Let's make a small API that handles a Like button. In our app.js:

const server = require('server');
const { get, post, del } = server.router;

// An array with the ids of the things we liked
const likes = [];

// Retrieve all of our likes
const show = get('/likes', ctx => {

// Create a new like
const add = post('/likes/:id', ctx => {
  let id =;
  ctx.res.json({ added: true });

// Remove a like
const remove = del('/likes/:id', ctx => {
  let id =;
  let index = likes.indexOf(id);
  likes.splice(index, 1)
  ctx.res.json({ deleted: true });

server(show, add, remove);

Now we can have a list of items that can be liked:

    <li>First <button data-id="1">Like</button></li>
    <li>Second <button data-id="2">Like</button></li>
    <li>Third <button data-id="3">Like</button></li>
    <li>Fourth <button data-id="4">Like</button></li>

<script src=""></script>
  // Load all the likes and add the class 'active' to the ones we liked
  fetch('/likes/').then(res => res.json()).then(likes => {
    likes.forEach(id => {

  // Handle the button clicks
  $('button').on('click', function(e){
    var id = $('data-id');
    var method = $('button');
    fetch('/likes/' + id, { method: method });

Exercise: make a dislike button that calls the route /dislike through POST and DELETE and shows on the browser console what the server is doing.


Deploy to Heroku

Then in a file called ".gitignore" we will write this. This will allow us for uploading only our own code while the hosting (Heroku) handles the dependencies: