Express.js Beginner Tutorial

Expressjs Beginner Tutorial

In this Express beginner tutorial, we can download and install Express.js to our system and see how to get a super basic skeleton application set up and configured. Thankfully, this is made pretty easy by the fact that there is a dedicated tool to create a new Express project automatically called Express Generator. Let’s take a look at how the complete beginner can get up and running with Express.js right away.

What is Express.js and why do we want to use it?

So at this point we have taken some time to get used to working with Node.js at a very basic level. We learned about what Node.js is, how to write and read data from the file system, handled some requests and responses, as well as set up our own basic routing system. If you take a look at the code in the routes tutorial, you’ll notice that it is kind of a lot of work to just set up some routes on our own. In addition, if we wanted to add multiple routes, it would not scale that well. Working with Node.js in it’s pure form requires that we write everything all on our own. This is prone to errors, is likely insecure, and just plain lots of work. Well guess what? Like most other things in software development, what you are trying to do has likely been done already with a stable and tested solution. This is why we are now moving on to taking a look at Express.js. Express will allow you to focus on your business logic and the needs of your application. The repetitive tasks like parsing urls and setting up manual routing can be handled by the framework. Express builds on Node and offers many tools that make working with Node easier. With Express, configuring routes becomes a breeze. The Express framework, created by TJ Holowaychuk, provides convenience methods and syntactic sugar for many common tasks that would otherwise be tedious and redundant.

How to setup and configure Express.js

The first thing we need to do is to install the express generator module on our system. It is super simple to do. Just type npm install -g express-generator at your command line, and this will install it for you.

C:node>npm install -g express-generator

Next up, let’s go ahead and create a new Express project using our newly installed Express Generator. All you have to do is type express and then the name of the project that you want to create. We will create a project named expressjs-tutorial. You’ll see that as the generator does it’s work, it gives you some output to show you the exact files and folders that it creates for your project.

C:node>express expressjs-tutorial

  warning: the default view engine will not be jade in future relea
  warning: use `--view=jade' or `--help' for additional options

   create : expressjs-tutorial
   create : expressjs-tutorialpublic
   create : expressjs-tutorialpublicjavascripts
   create : expressjs-tutorialpublicimages
   create : expressjs-tutorialpublicstylesheets
   create : expressjs-tutorialpublicstylesheetsstyle.css
   create : expressjs-tutorialroutes
   create : expressjs-tutorialroutesindex.js
   create : expressjs-tutorialroutesusers.js
   create : expressjs-tutorialviews
   create : expressjs-tutorialviewserror.jade
   create : expressjs-tutorialviewsindex.jade
   create : expressjs-tutorialviewslayout.jade
   create : expressjs-tutorialapp.js
   create : expressjs-tutorialpackage.json
   create : expressjs-tutorialbin
   create : expressjs-tutorialbinwww

   change directory:
     > cd expressjs-tutorial

   install dependencies:
     > npm install

   run the app:
     > SET DEBUG=expressjs-tutorial:* & npm start

For this example, we now make use of Visual Studio Code and choose the ‘Open Folder’ option to open up the folder which was just created.
express generator folder structure


As part of the project creation, Express Generator fills out a package.json file which provides a list of the dependencies needed to create a skeleton application in Express.

  "name": "expressjs-tutorial",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  "dependencies": {
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "express": "~4.16.0",
    "http-errors": "~1.6.2",
    "jade": "~1.11.0",
    "morgan": "~1.9.0"

These dependencies are not yet installed, so you need to change into the directory which holds the package.json and run npm install to complete the process.

C:node>cd expressjs-tutorial

C:nodeexpressjs-tutorial>npm install

Once this step is complete, you will now have a node_modules folder which actually holds all of those dependencies which were just downloaded to your machine using npm.
node_modules folder holds dependencies

Start Express!

You are ready to start the Express application. To do so, simply type npm start in the root of the project.

C:nodeexpressjs-tutorial>npm start

> expressjs-tutorial@0.0.0 start C:nodeexpressjs-tutorial
> node ./bin/www

Now, go ahead and open up your browser at http://localhost:3000/ and check it out!
welcome to express

The bin/www and app.js files

These two files are pretty important in an Express application, so let’s take a quick look at what they are doing for us.

The www Server File

The /bin/www file is the application entry point for Express. The very first thing this does is to require() the “real” application entry point, which is app.js, that sets up and returns the express() application object. Here is the code contained in that file.

#!/usr/bin/env node

 * Module dependencies.

var app = require('../app');
var debug = require('debug')('expressjs-tutorial:server');
var http = require('http');

 * Get port from environment and store in Express.

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

 * Create HTTP server.

var server = http.createServer(app);

 * Listen on provided port, on all network interfaces.

server.on('error', onError);
server.on('listening', onListening);

 * Normalize a port into a number, string, or false.

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;

  if (port >= 0) {
    // port number
    return port;

  return false;

 * Event listener for HTTP server "error" event.

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;

  var bind = typeof port === 'string' ?
    'Pipe ' + port :
    'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      throw error;

 * Event listener for HTTP server "listening" event.

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string' ?
    'pipe ' + addr :
    'port ' + addr.port;
  debug('Listening on ' + bind);

Here are a few quick takeaways of the bin/www server file in Express.

var app = require(‘../app’); The app file gets loaded here.

var debug = require(‘debug’)(‘expressjs-tutorial:server’); Sets the server debug and name.

var http = require(‘http’); Loads the http module that we learned about in the html rendering tutorial.

var port = normalizePort(process.env.PORT || ‘3000’); Turns the string value of ‘3000’ into an integer.

app.set(‘port’, port); Sets the port the application should use to listen on.

var server = http.createServer(app); The server is created like we saw in our Node routes tutorial.

server.on(‘error’, onError);
server.on(‘listening’, onListening);
Sets up the listening as well as the error and listening events.

The app.js file

The app.js file creates an express application object which is named app by convention, and sets up the application with various settings and middleware. It then exports the app from the module. Here is the code in the app.js file.

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

  extended: false
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error ='env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);

module.exports = app;

Some key points about the app.js file.
var createError = require(‘http-errors’);
var express = require(‘express’);
var path = require(‘path’);
var cookieParser = require(‘cookie-parser’);
var logger = require(‘morgan’);

At the top of the file, there are several imports that Express needs to do it’s work.

var indexRouter = require(‘./routes/index’);
var usersRouter = require(‘./routes/users’);

These are the two sample routes provided by Express when you first create a project with the Express Generator.

var app = express();
The application gets created here.

app.set(‘views’, path.join(__dirname, ‘views’));
app.set(‘view engine’, ‘jade’);
Here is where you can configure the templating engine used. By default it uses Jade.

set views directory node jade

extended: false
Here is where the logger, json, urlencoded, and cookie parser middlewares are specified.

app.use(express.static(path.join(__dirname, ‘public’))); How to set the public folder in Express.

set express public folder

app.use(‘/’, indexRouter);
app.use(‘/users’, usersRouter);
Basic routes for / and /users are specified here.

Inspecting The index.js and users.js route files

We can see that in the app.js file, if a user requests the / route then the indexRouter is used by this code app.use('/', indexRouter);. Now indexRouter actually holds what is contained in index.js. This is specified by var indexRouter = require('./routes/index'); Let’s look at that file.


var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });

module.exports = router;

Here is where the action starts happening. At the top of the file, the express router is required and initialized into the router variable. After that we can see that a get() function is called. That function accepts two arguments.

The first argument is the path of the route. In this case of course, it is simply / or the home page.

The second argument is a function which itself takes three arguments. This function takes the request, the response, and the next arguments.

Inside this function, a call to render() is made. We can see that ‘index’ is the first argument. What this is saying is to look in the views folder for a file that has the name of index before the extension. In the views folder there is an index.jade file. This is the file being referenced. The second argument to the render() function is a JavaScript object. It is in this object where variable data can be passed to the view as it is being rendered. In fact, let’s make a quick change to this file.

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'I am learning Express!' });

module.exports = router;

Go ahead and restart the application from the command line by typing ctrl-c

Terminate batch job (Y/N)? y

Restart with npm start

C:nodeexpressjs-tutorial>npm start

Once the server is restarted, you can see that by updating the title property of the JavaScript object, our data is updated in the web browser.
indes route expressjs

The key concept is that we are rendering a template file, and passing in dynamic data to that file so that it can be used in the view. This concept is the same across many different frameworks and many different programming languages for that matter.

Sub Routes

Now we can look at the users.js file.


var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');

module.exports = router;

Notice anything? The users.js file is using the same / path. How can this be? This is because in app.js, it was already defined that /users would use users.js. Therefore inside users.js, we do not have to specify the full /users path. In fact if we did, that would equate to /users/users and that is not what we want. The key is that the path seen in the actual routes file is relative to the path specified in app.js. To see how this works, we can add another route to users.js.

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function (req, res, next) {
  res.send('respond with a resource');

router.get('/stats', function (req, res, next) {
  res.send('Stats about the user');

module.exports = router;

What this does is set up a new route that can be visited at http://localhost:3000/users/stats
sub route express example

Single File Routing

We now see how routing works on a fresh install of Express.js. Maybe you would rather have a single point of entry so to speak, and just put all of your routes in one file. You can do this as well if you like. Let’s see how.

First, remove var usersRouter = require(‘./routes/users’); from app.js.
remove users route

Next, remove app.use(‘/users’, usersRouter); from app.js.
remove app-use users

Finally, you can consolidate all of your routes in that index.js file like so.

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  res.render('index', {
    title: 'I am learning Express!'

/* GET users listing. */
router.get('/users', function (req, res, next) {
  res.send('respond with a resource');

router.get('/users/stats', function (req, res, next) {
  res.send('Stats about the user');

module.exports = router;

Notice however that we need to specify the full path when putting all of the express routes in the same file versus putting each route into its own file. Both approaches work, it all depends on what makes the most sense to you and your needs. We now see how a basic skeleton express application is set up and how it works.

Express.js Beginner Tutorial Summary

You have now created a skeleton website project using the Express Generator and confirmed that it runs using node. By looking at the files and folders that are created for us, you also understand how an Express application is structured. Here are some key topics about Express and Node to keep in mind.

  • Express works by following a Request Processing Pipeline architecture
  • An Express application is mostly a collection of middleware functions all working together.
  • A middleware function is a function that takes a request object and either terminates the request/response cycle or passes control to another middleware function.
  • Express has several built in middleware functions
    • json(): used to parse the body of requests with a JSON payload
    • urlencoded(): used to parse the body of requests with URL-encoded payload
    • static(): used to serve static files
  • Anyone can create custom middleware and use it in the Request Processing Pipeline
  • // Custom middleware (applied on all routes)
    app.use(function(req, res, next)) {
    // …
    // Custom middleware (applied on routes starting with /api/v1)
    app.use(‘/api/v1’, function(req, res, next)) {
    // …
  • You can detect the environment in which our Node application is running using process.env.NODE_ENV and app.get(‘env’).
  • The config package is a great way to store configuration settings for our applications.
  • We can use the debug package to add debugging information to an application for more power than console.log().
  • You can use a templating engine to return HTML markup to the client. Jade(Pug), EJS and Mustache are the most popular ones.

To learn more about how the basic Express structure works, check out the mozilla express tutorial.