---
title: "Build a web server using Express"
url: "https://www.pardel.dev/2024/09/14/web-server-express"
date: 2024-09-14
author: "Paul Ardeleanu"
tags: ["JavaScript"]
description: "In this post, we will build a simple web server using Express, a popular web framework for Node.js, and a templating engine called Pug."
---

# Build a web server using Express

> Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

## Installation

In the terminal, we'll create and navigate to a folder that will host our server - we're using a folder named `my_server` located in the home directory:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev"><code class="language-bash">mkdir ~/my_server
cd ~/my_server</code></pre>

Next step is to initialise your application:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-20"><code class="language-bash">npm init -y
Wrote to /Users/pardel/my_server/package.json:

{
  "name": "my_server",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}</code></pre>

We'll also create the file that will act as the entry point:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev"><code class="language-bash">touch index.js
</code></pre>

To add `Express` to our app, we'll run the following in the terminal:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-20"><code class="language-bash">npm install express --save

added 65 packages, and audited 66 packages in 1s

13 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities</code></pre>

## A Simple Server

We'll add a single endpoint that will display a simple "Hello World" message - add the following to the `index.js` file created above:

<pre><code class="lang-js">const express = require('express');
const app = express();
const port = 5550;

app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(port, () => {
  console.log(`Server started at http://localhost:${port}`);
});</code></pre>

## Run

To start the server, we'll run the following in the terminal:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-3"><code class="language-bash">node index.js
Server started at http://localhost:5550
</code></pre>

Now, if you point our browsers to http://localhost:5550, we'll see a webpage containing the 'Hello World' message:

## Avoid relaunch

One of the limitations we're going to encounter, is the need to relauch it if changing to the `index.js` file.

A great utility to use for overcoming this limitation is [`nodemon`](https://nodemon.io/) - to install it please run the following:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-10"><code class="language-bash">npm install -g nodemon

changed 29 packages in 687ms

4 packages are looking for funding
  run `npm fund` for details</code></pre>

Launching the server will now be done by replacing `node` with `nodemon`:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-10"><code class="language-bash">nodemon index.js
[nodemon] 3.1.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node index.js`
Server started at http://localhost:5550
</code></pre>

## Templating engines

Express supports a lot of [templating engines](https://expressjs.com/en/guide/using-template-engines.html) - we're going to use one called `pug`. To add it to our app:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev" data-output="2-10"><code class="language-bash">npm install pug --save
added 39 packages, and audited 105 packages in 2s

18 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities</code></pre>

### Integrate

Next, we'll integrate it into our app inside `index.js` - at the top of it, before defining the endpoints, set the engine and the views folder (lines 5-6 below):

<pre><code class="lang-js">const express = require('express');
const app = express();
const port = 5550;

app.set('view engine', 'pug');
app.set('views','./views');
...
</code></pre>

### Views

You'll notice above that we're going to use a folder named `views` to store our `pug` templates. Let's create it together with a `index.pug` file inside:

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev"><code class="language-bash">mkdir views
touch views/index.pug
</code></pre>

### First template


Let's add our first view - add the following as the content of the `views/index.pug` file:

<pre><code class="lang-html">doctype html
html
   head
      title Hello World
   body
      p Welcome to my website
</code></pre>

### Using the template

Back in `index.js`, let's make use of the new template - for the `/` endpoint, we'll replace the `res.send` with `res.render` (line 9 below):

<pre><code class="lang-js">const express = require('express');
const app = express();
const port = 5550;

app.set('view engine', 'pug');
app.set('views','./views');

app.get('/', (req, res) => {
  res.render('index');
});

app.listen(port, () => {
  console.log(`Server started at http://localhost:${port}`);
});
</code></pre>

### Relaunch the server

<pre class="command-line no-line-numbers" data-title="command line" data-user="pardel" data-host="dev"><code class="language-bash">nodemon index.js</code></pre>

The reloaded webpage, http://localhost:5550, will now contain HTML as per the template - the browser window title now shows: 'Hello World' and its content is: 'Welcome to my website'.

## What next?

- [Express website](https://expressjs.com)
  - [Express API reference](https://expressjs.com/en/4x/api.html)
- [Pug - Getting Started](https://pugjs.org/api/getting-started.html)
- [Nodemon website](https://nodemon.io/)
