Introduction to Express.js

From official documentation, Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It is one of the most popular frameworks built on top of Node.js and is widely used by technology companies.

Express identifies itself as an unopinionated web framework meaning there are fewer restrictions in terms of how you structure your project, how you write code, how you implement design patterns and style guides. It doesn't force anything and gives a lot of flexibility to the developers to make decisions that best suits their application needs. Sometimes, this flexibility can cause chaos as well in projects if proper care is not taken. In opinionated web frameworks, there is a preferred way of doing things and everyone has to follow that way in order to  achieve goals smoothly and efficiently. This makes it developers follow a same coding architecture, style and guidelines which makes it very easy to develop a software and also maintain it. Some people prefer opinionated frameworks while other prefer unopinionated frameworks. Both has it's pros and cons.

Express.js provides a lot of features that makes it easy to create applications. Some of the features are listed below:

  • Routing

    It provides a robust routing feature which can be used to create HTTP endpoints to handle any kind of client requests with relative ease.

  • Middlewares

    It provides a middleware functionality which can be used to intercept the application's request-response mechanism. Using middleware functions, we can modify the client requests and also the response that we are sending for that request and inject additional parameters, modify the behavior of the requests, implement various checks like payload validation, authentication checks etc.

  • Templating Engines

    It provides a templating engine which allows dynamic rendering of web pages using static template files.

  • Error Handling

    With express.js, a default error handler is already provided meaning we don't need to build our own error handling mechanism and can easily use those default error handlers to handle errors.

  • Utility Functions

    Express.js provides a lot of commonly used utility functions.

and many others. We will get into each of these in detail in later chapters. Now, its time to get into coding.

Express.js is one of the most popular package hosted in the npm package registry At the time of writing this article, weekly downloads is around 19 millions. Before we can use it, we need to create a file called package.json at the root of the project directory. This file contains all the metadata information about the project such as name of the project, detail information about the project, author, git repository, license information, tracks all the third party npm packages that the project is using along with its versions and scripts that we can use to run the project and do various other actions like running tests, checking outdated packages.

Let's create a project directory and name it as travel-app

   	mkdir travel-app
   	cd travel-app/

From travel-app directory, Let's create a package.json file. We can create it both manually as well as using a npm init command. Let's use command.

   	npm init

This command will prompt you for various information about the project. If the information shown in the prompt in between parenthesis () is good, just press enter key and if it shows blank, you can type as you wish or leave as it is and press the enter key. In the below picture, there is a placeholder for git repository. If you are familiar with git, that's great. If you are not, then we will also discuss about it in detail later.

npm init command

As you can see, it prompts for package name(project name), version, description, entry point (this is the main filename which will be used to run the express application), git repository (if you don't know git, leave it blank for now) and various others. After you are done entering all the prompted metadata information about the project, press enter key and it will ask for the confirmation. Type yes

npm init command confirmation

In the root of the project directory, you will now see package.json file. You can also manually edit this file if any modification needs to be done.

Time to install express.js from npm package registry. Issue the following command to install the package in our root directory.

   	npm install express

This command downloads the express package from the npm registry and installs it inside of node_modules folder. node_modules folder is automatically created by npm at the project root directory and contains all the locally downloaded npm packages. Whenever we import the package in our files, Node.js will check the node_modules directory for the imported package. If the package do not exists in the node_modules directory, server throws an error.

Also check the package.json file. You will see some new sections containing metadata information about recently installed express package:

   	"dependencies": {
	    "express": "^4.18.1"

The dependencies field is one of most important field in package.json file and is used to list all the npm packages required to run our application. When we install the package using npm install command, it downloads the package to the node_modules directory and then also write the package name along with its version in dependencies  field. The version of the packages follows the semantic versioning. Refer to the following link to know more about semantic versioning.

dependencies field is used to list only the packages that are required to run the application in production which means the packages that are not needed to run the application in production systems, we should not list them there. There is a separate field in the package.json file called devDependencies for listing all the packages that are only required for development purposes.

To install the package as dev dependency:

   	npm install jest --save-dev

As you can see, there is an additional --save-dev which explicitly tells that the package is only necessary for development purposes. jest is one of the most popular testing framework for javascript which we will use later on for writing unit tests.

Now check the package.json file looks like below:

	  "name": "travel-app",
	  "version": "1.0.0",
	  "description": "Travel application",
	  "main": "index.js",
	  "scripts": {
	    "test": "npm run test"
	  "repository": {
	    "type": "git",
	    "url": "git+"
	  "keywords": [
	  "author": "Shrawan Lakhe",
	  "license": "MIT",
	  "bugs": {
	    "url": ""
	  "homepage": "",
	  "dependencies": {
	    "express": "^4.18.1"
	  "devDependencies": {
	    "jest": "^28.1.2"


Now that we have package.json file ready, let's create a simple express.js server:

Create a file called index.js. Note that the file name should be exactly as the one we see in the package.json file with main property. If you want to use different filename, then also change the filename in package.json file with main property.

   	touch index.js

At the top of the file, we need to first import express.js package. To import a package, we need to call the require function with the name of the package

   	const express = require('express');

After importing express.js package, we need to create an instance of express application.

   	const app = express();

Now, that we have an instance of the express application ready, we can now start listening on that application on some ports. Let's use 3000 for port.

   	const port = 3000;
   	app.listen(port, () => {
	  console.log(`Travel application listening on port ${port}`)

That's it. Our express web server is ready. This is how simple it is. But wait, server is ready but we are not exposing any routes or endpoints to which client's can make a request. It's extremely easy to create routes with express. The instance of an express application exposes various methods and properties that we can use and one of those is the routing functionality as well.

There is app.get(path, callback, [...callbacks]) functionality which we can use to route HTTP GET requests to the specified path with the specified callback functions. Let's expose the index route i.e. (/) and return Hello World message on that route.

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

Our basic express server is ready to listen to the client requests on the index route. Requests on any other route or endpoint will have 404 HTTP response meaning route is not found. Run the server using following command:

   	node index.js

You should see the following output.

Simple Express web server

Make a GET request to the index route using CURL

   	curl -v http://localhost:3000/
GET request to the express application

We can see Hello World! in the response. Congratulations, You have your basic web server ready built using Express.js.

Here, we run the application using node index.js command. You might wonder if there is even better way of running express applications now that we have package.json file, well, there is. We have briefly discussed about the scripts property in package.json file earlier.

   	 "scripts": {
	    "test": "npm run test"

Let's write another line to this scripts property which will run the express application.

   	 "scripts": {
	    "test": "npm run test",
        "start": "node index.js"

Now, we can just enter either of the following commands to start the server.

   	npm start


   	npm run start

This gives a lot of flexibility  in terms of how we run various commands associated to this application. Right now commands are simple but we can have much more complex commands in the scripts property. Scripts are most commonly used for running an application, running tests, checking outdated packages etc. Anything defined in scripts property, we can run it using npm run scriptName command.

npm scripts to run express application

For this article, this is all we have. In next chapter, we will extend our travel-app application to define more routes/endpoints using express routing functionality.

Prev Chapter                                                                                          Next Chapter