Express is a web framework for Node, inspired by the Sinatra framework for Ruby. It boasts loads of features, high performance, and comes with a handy executable for creating applications quickly. In this article we’re going to look at how you can get up and running with express, what you get when you create a new express website, and finish with adding a route and view to display search results from Twitter.

Installing Express

Express can easily be installed via npm (Node Package Manager):


$> npm install express -g

The -g switch on the end makes express available globally. This means we can run the express executable from anywhere to quickly create a new application. The express executable is called, unsuprisingly, express:


$> type express
express is hashed (/usr/local/bin/express)

If you type in the command by itself, express will create a new application in the current directory. If the current directory isn’t empty, you’ll be prompted and asked if you want to continue:


$> express
destination is not empty, continue? 

Enter ‘y’ if you want to carry on, or ‘n’ to abort. You’re not restricted to creating new apps in the current directory, you just need to pass express the path to where you want your new application created. You can pass it other options as well:

  • -s to enable sessions
  • -t or --template <engine> to specify your template engine (express uses jade by default)
  • -c or --css to add stylus CSS support (the default is plain CSS)
  • -v or --version to output the current version of express you’ve got installed
  • -h or --help to output this help and exit

A list of supported template engines is on the express guide, and also on the express wiki. In this article we’ll use EJS. Let’s create a new site called myapp:


$> express -t ejs myapp

create : myapp
create : myapp/package.json
create : myapp/app.js
create : myapp/public
create : myapp/routes
create : myapp/routes/index.js
create : myapp/views
create : myapp/views/layout.ejs
create : myapp/views/index.ejs
create : myapp/public/javascripts
create : myapp/public/images
create : myapp/public/stylesheets
create : myapp/public/stylesheets/style.css

dont forget to install dependencies:
$> cd myapp && npm install

express creates a new site in the myapp folder for us. We get: a package.json file, an app.js file for application code, a routes directory for routes, a views directory for our view templates, and a public directory for our CSS, images and client-side JavaScript. Express also reminds us to install dependencies and gives us the command to do so. We might as well type that in now before we forget:


$> cd myapp && npm install
npm http GET https://registry.npmjs.org/express/2.5.5
npm http GET https://registry.npmjs.org/ejs
npm http 304 https://registry.npmjs.org/ejs
npm http 304 https://registry.npmjs.org/express/2.5.5
npm http GET https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/qs
npm http GET https://registry.npmjs.org/mkdirp/0.0.7
npm http GET https://registry.npmjs.org/connect
npm http 304 https://registry.npmjs.org/mime
npm http 304 https://registry.npmjs.org/qs
npm http 304 https://registry.npmjs.org/mkdirp/0.0.7
npm http 304 https://registry.npmjs.org/connect
npm http GET https://registry.npmjs.org/formidable
npm http 304 https://registry.npmjs.org/formidable
ejs@0.6.1 ./node_modules/ejs 
express@2.5.5 ./node_modules/express 
├── mkdirp@0.0.7
├── qs@0.4.2
├── mime@1.2.5
└── connect@1.8.5

You should see something similar, although the exact output may differ depending on which versions of the dependencies are available via npm, and which you already have installed. If you now type in node app.js and browse to http://localhost:3000 you should see the Welcome to Express page. Let’s have a look at the code express has generated and how it’s used to by the welcome page.

app.js

app.js is where you configure your site, and define your routes. The app variable is our express server, and we call it’s configure function to tell express which view engine to use, where to find static resources, and how to handle errors. Look at the default app.js code you’ll see that app.configure is called three times:

  • the first time it’s called without a name argument – this will apply the settings to every environment
  • the second time it’s called with development as the first argument – these errorHandler settings will only be applied in the development environment
  • the third time it’s called with production as the first argument – the errorHandler in the production environment will have exceptions dumps and stack traces turned off

Now look at the last two lines in app.js:


app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);	

This tells express which port to listen for connections on, then logs a message to the console confirming the port it’s listening on, as well as the current environment.


$ node app.js 
Express server listening on port 3000 in development mode

By default app.settings.env is set to development. To change this to another environment, e.g. production, insert the following line above the call to console.log:


app.settings.env = 'production';

Restart the app ctrl+c, then type in node app.js again), and mode should have changed to production:


$ node app.js 
Express server listening on port 3000 in production mode

Routing

Express exposes the 6 HTTP verbs as it’s API for defining routes, and lets you capture parameters via named parameters, wildcards, regular expressions, and combinations of all three. Captured values will be accessible via req.params:


// using a named parameter
app.get('/foo/:id', function(req, res) {
	var fooId = req.params.id;
	...
});

// using regular expressions
app.get(/^/foo/(d+)/, function(req, res) {
	var fooId = req.params[1];
	...
});

// using a combination of the two
app.get('/foo/:id([0-9]+)', function(req, res) {
	var fooId = req.params.id;
	...
})

All three routes above show different ways of getting the fooId from the URL.

In app.js you’ll see the route defined for the welcome page. This handles GET requests to ‘/': when a request is received for this path the callback function routes.index is fired.

.

The routes.index function is defined in routes/index.js. routes/index.js is a module that exports functions to be used as route handlers. If you open it up you’ll see the code that makes up the routes.index function:


exports.index = function(req, res){
  res.render('index', { title: 'Express' })
};	

This tells express to render the index view. The object passed as the second argument to render is data that will be made available to the view.

Views

When we created myapp we told express to use the EJS template engine. If you look in the views folder, you’ll see that express created a couple of files for us: a layout.ejs file, and an index.ejs file. layout.ejs is where the bulk of the page layout HTML lives, with index.ejs containing page-specific HTML. If you open up layout.ejs you’ll see something like this:


<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel="stylesheet" href="/stylesheets/style.css" />
  </head>
  <body>
    <%- body %>
  </body>
</html>

Aside from the regular HTML, the title from the object we passed to the view gets output in the <title> tag, and content from page-specific templates (such as index.ejs) gets included via the <%- body %> line. Let’s open index.ejs to see what’s in there:


<h1><%= title %></h1>
<p>Welcome to <%= title %></p>

Again we’re outputting the title from the object we passed to the view, first in the <h1&t; tag, and then in the <p> tag. If you change the value assigned to title in routes/index.js and restart the app, you should see the value change when you refresh your browser.

Adding a New Route

Let’s add a new route and view that’ll display the ten most recent tweets mentioning Sitepoint. We’ll need to add a route to app.js, a callback function for the route, and a view to display the tweets:

  1. Open app.js and add a route for the tweets page:

    
    app.get('/twitter', routes.twitter);
    
  2. Next, open up routes/index.js and add this line at the top to import the http module:

    
    var http = require('http');
    
  3. Stay in routes/index.js and add the following function:

    
    /*
     * GET twitter search results
     */
    exports.twitter = function(req, res) {
      var options = {
        host: 'search.twitter.com',
        port: 80,
        path: '/search.json?q=sitepoint&rpp=10'
      };
    
      http.get(options, function(response) {
        var tweets = '';
        response.on('data', function(data) {
          tweets += data;
        }).on('end', function() {
          var tmp = JSON.parse(tweets),
            topTen = tmp.results;
          res.render('twitter', { title: 'Latest from Twitter', tweets: topTen });
        });
      }).on('error', function(e) {
        res.writeHead(500);
        res.write('Error: ' + e);
      }); 
    }
    

    Here we’re using http.get to make a HTTP GET request to the Twitter Search API. We pass http.get the options object, which tells it where to get the data from. We then define a couple of callback functions: on('data', ...) appends data to tweets each time some data is received; on('end', ...) is called when all data has been received, and sends the tweets to the twitter view.

  4. Finally, create a twitter.ejs file in your views folder. Open the file and add the following:

    
    <h1><%= title %></h1>
    <% if (tweets.length) { %>
      <ul>
        <% tweets.forEach(function(t) { %>
          <li>
            <h2>
              <a href="http://twitter.com/<%= t.from_user %>" rel="external">
                <%= t.from_user_name %>
                <span><%= t.from_user %></span>
              </a>
            </h2>
            <blockquote>
              <p><%= t.text %></p>
            </blockquote>
            <a href="http://twitter.com/#!/<%= t.from_user %>/status/<%= t.id %>" rel="external">Open</a>
          </li>
        <% }); %>
      </ul>
    <% } // endif %>
    

    After displaying the title, the view checks that we have some tweets to display. If we do, forEach iterates through each tweet, using the callback function to display the tweet’s text, and who the tweet was from.

Restart the app, then browse to http://localhost:3000/twitter and, if all went well, you’ll see a list of the ten most recent tweets mentioning Sitepoint.

So that was a quick introduction to creating a website in Node using the express web framework. We looked at what express gives you when you create a new express site, had a quick look at how it uses routing and views, and added a new route and view to display search results from Twitter. There’s a lot more that express is capable of, and a lot that we haven’t covered. If you’re interested in finding out more then head over to http://expressjs.com/guide.html, and have a look at the express wiki.

Ian Oxley
Ian Oxley has been building stuff on the Web professionally since 2004. He lives and works in Newcastle-upon-Tyne, England, and often attends local user groups and meetups. He's been known to speak at them on occasion too. When he's not in front of a computer Ian can be found playing guitar, and taking photos. But not usually at the same time.

  • http://shoutdigital.com Luke Browell

    Hi Ian,

    Thanks – Great run through of Express features.

    Node really comes into it’s own with websocket, have you had any success using websocket alongside express?

    Luke

    • http://ianoxley.com Ian Oxley

      Hi Luke

      I’ll be writing about Node and socket.io in a few weeks, so might try and work something into the article about using WebSockets / socket.io with express.

  • TJ Holowaychuk

    Nice post! keep in mind the ideal way to manipulate the environment is with:

    $ NODE_ENV=production node app

    this way on your server you can just export NODE_ENV=production

Related books & courses
Available now on SitePoint Premium

Preview for $1