Build A static node js web app with express

Express is a popular web framework that helps us create a node js web app with minimum configuration.

In the previous post, we learned the basics of node js, npm, and how to create a simple web server with the help of node js.

In this article, we will learn how to create a simple static web app with the help of the express web framework.

Table of Contents

Creating the hello world node js app with express js

Create a directory with the name express-static-app, navigate inside the directory and run the command npm init.

npm init command to initialize the express app

Create an index.js file in the current directory. This file is the entry point of the application.

Next, we will install the required node js libraries to our application.

Installing the express package

To add the express package, run the command npm i express -s.

install express

This will install the express package into our application as a dependency.

Now, we can start using the express package to create a simple web server.

Update the index.js file with the below content.

const port = 3000,
    express = require("express");
app = express();
app.get("/", (req, res) => {
    console.log(`request recieved at:${req.url}`);
    res.send("Hello Universe!");
app.listen(port, () => {
    console.log(`The Express.js server has started and is listening on port number: ${port}`);
  • We have imported the express js package and initiated it.
  • The get() function of the express framework helps to handle incoming HTTP GET requests.
  • The configuration on line number 6 handles the HTTP requests made to the URL /.
  • We are calling the listen() function and passing the port number that the application should use.

Start the application by executing the command node index.js

Access the application using a web browser at http://localhost:3000.

express hello universe app

We can also observe that the application runs on port number 3000, and the express framework handles the incoming user request.

express server example

Building routes using express

Next, we will create the URL routes that serves the content for our application.

Creating controller layer

Create a directory called controllers under the base directory of the application and create a staticAppController.js file.

We will segregate the request handling into this file to keep the application structured.

exports.hello = (req, res) => {
    console.log(`request recieved at:${req.url}`);
    res.send("Hello Universe!");

We have moved the existing logic of the app that we have created earlier to a new file.

Now we can import the controller file in the index.js file, as shown below.

const staticAppController = require("./controllers/staticAppController");
app.get("/", staticAppController.hello);

Start the application. If everything is fine, we should get the same screen with “Hello Universe”.

Creating a static web app with express

So far, we have learned how easy it is to work with express js.

In this section, we will create a static web app. We will also learn how to handle POST requests, serving the static files, error handling, etc.

We will also configure the bootstrap CSS support.

Setting up the application

Install the bootstrap package by executing the command npm i bootstrap -s.

bootstrap with express

Install the EJS package by executing the command npm install ejs -s.

express ejs

Embedded JavaScript(EJS) helps us to apply the javascript functions and variables within our views. EJS view files have .ejs the extension.

Finally, install the ejs-layouts package by executing the command npm install express-ejs-layouts -s.

express ejs layouts

Layouts help us create a fixed layout shared across the application. For example, We can display the same header and footer content across the application pages.

Create the required files and folders

Let us create the required views, public files controllers, etc.


Create a folder with the name views under the application’s home directory.

The EJS library uses this folder to render the appropriate views.

Create a file called index.ejs and add the the below content.

<main role="main" class="container">
    <h1 class="mt-5">My Website</h1>
    <h2>My subscribers list</h2>
    <table class="table">
                <th scope="col">Name</th>
                <th scope="col">Email</th>
            <% mySubscribers.forEach(subscriber=> { %>
                        <%= %>
                        <%= %>
            <% }); %>
  • The index.ejs file is our home page of the static web application. We display the subscribed user details on this page.
  • The lines highlighted above show that how EJS is helpful to add the javascript functions and access javascript variables inside the view pages.

Similarly, Create a subscribe.ejs and thankyou.ejs files in the same directory.

<main role="main" class="container">
    <h1 class="mt-5">Subscribe to my website</h1>
        <form action="/subscribe" method="post">                   
            <input type="text" name="name" placeholder="Name">
            <input type="text" name="email" placeholder="Email">
          <input type="submit" name="submit">

The below is the thankyou.ejs file.

<main role="main" class="container">
    <h1 class="mt-5">Thank you for subscribing to my web site</h1>

The subscribe.ejs view file is used to capture the user details and after successful submission, a thank you message is displayed to the user.

Creating the view layout

As we have added the ejs-layouts package to our application, we can use this to create a fixed page structure across all application pages.

Create a new folder called partials under the views folder and create new file navigation.ejs.

    <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
                <a class="nav-link" href="/">Home</span></a>
            <li class="nav-item">
                <a class="nav-link" href="/subscribe">Subscribe</a>

Create a layout.js file and add the below content.

<!doctype html>
<html lang="en">
    <meta charset="UTF-8">
    <title>My express app</title>
    <link href="./css/bootstrap.css" rel="stylesheet" type="text/css">
<body data-new-gr-c-s-check-loaded="14.1018.0" data-gr-ext-installed="">
    <%- include('partials/navigation') %>
    <%- body %>
    <script src="./js/bootstrap.js" type="text/javascript"></script>
  • We have the complete HTML structure in this view with html, header, and body tags.
  • We are importing the bootstrap CSS on line number 7 and bootstrap JS file on line number 13 in this layout file, as it will be available across the application pages.
  • Line number 11 shows how to import a partial view like a navigation bar.
  • Line number 12 inserts the currently rendered view content to this location.
  • The layout.js file of our application will display a consistent navigation bar across all pages of our application. These pages can be either index.ejssubscribe.ejs or thankyou.ejs in our example.

Creating a static error page

Create a folder with the name public and add an error.html file as shown below.

The page displays an error message for errors like page not found(404), etc.

<!doctype html>
<html lang="en">
    <meta charset="UTF-8">
    <title>My express app</title>
    <link href="../css/bootstrap.css" rel="stylesheet" type="text/css">
<div class="alert alert-danger" role="alert">
    Opps!! something went wrong!!

Wiring it all together

We have set up all the required page and layout views in the previous section.

Now we will create the required controller layer to handle the requests made on different URLs and serve appropriate views.

Finally, we will modify the index.js file by adding necessary package imports and configuration to use EJS and express-layouts packages and custom controllers.

The controller layer

We will modify the existing staticAppContoller.js file and add a new controller js file to handle the application errors.

The main controller

Update the staticAppController.js file with the below content.

const subscribers = [];
exports.getHomePage = (req, res) => {
    res.render("index", { mySubscribers: subscribers });
exports.getSubscribePage = (req, res) => {
exports.saveSubscriber = (req, res) => {
  • The “subscribers” array holds the subscriber list of our application.
  • The “getHomePage” function renders the index.ejs file and also adds the subscriber list to the response.
  • The “getSubscriberPage” function renders the subscribe page.
  • The “saveSubscriber” function adds the subscriber data submitted by the user into the existing subscriber list.
Handling error on node js express application

Let us create an errorController.js controller file that handles the HTTP 404 or 500 errors.

exports.pageNotFoundError = (req, res) => {
exports.internalServerError = (error, req, res, next) => {
    console.log(`ERROR occurred: ${error.stack}`);
  • If the defined request handlers are not handling the incoming request on a specific path, the application invokes the function pageNotFoundError.
  • The application invokes the internalServerError function if any application error occurs during runtime, and the browser renders a static error page.

Updating the index.js file

Update the index.js file with below content.

const port = 3000,
    express = require("express")
    layouts = require("express-ejs-layouts");
app = express();
const path = require('path');

app.use('/css', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/css')))
app.use('/js', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/js')))
app.use('/js', express.static(path.join(__dirname, 'node_modules/jquery/dist')))
app.use('/html', express.static('./public'))
app.set("view engine", "ejs");

//Parse URL encoded data and use JSON format.
app.use(express.urlencoded({ extended: false }));
const staticAppController = require("./controllers/staticAppController");
const errorController = require("./controllers/errorController");
app.get("/", staticAppController.getHomePage);
app.get("/subscribe", staticAppController.getSubscribePage);"/subscribe", staticAppController.saveSubscriber);
app.listen(port, () => {
    console.log(`The Express.js server has started and is listening on port number: ${port}`);
  • We have imported the “express-ejs-layouts” package that enables EJS layout support to our application.
  • We have configured the static file paths and this includes bootstrap file directories and the public directory that we have added under earlier.
  • The app.set(“view engine”, “ejs”) configures EJS as the view engine of the application.
  • Also, we have added the imported layouts package to enable the view layout support.
  • The line number 17 and 18 enables the parsing of the URL encoded data into the JSON format.
  • We also have imported the controllers, that are responsible for rendering the views or processing the data submitted by the user.
  • Finally, we have configured the application to use the error controller methods that are defined in the errorController.js file.

Running the static app

To run the application, we can use the command node index.js.

We can also add a start script to the package.json file and launch the application by executing the “npm start” command.

  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start" : "node index.js"

Initially, the home page will have empty subscribers list, as shown below.

node express static app example

Click on the Subscribe link on the navigation bar, enter the details and submit the form.

node express static web app example

A successful message is displayed after user submits the form.

node express static web app example

Navigate back to the Home page. The page displays the subscribers list on the screen.

node express static web app example

Try to access a random URL, and the page redirects to the error page.

node express error page example


In this article, we learned how to create a simple node js web app with the help of the express framework.

We also added bootstrap css and added some custom styling to our application.

We also learned how to serve the ejs files and display data using the express-ejs-layout package.

The code is available on Github.