Node Tutorial Part 2

2010-11-08 00:00:00 +0000 by Alex R. Young

Welcome to part 2 of Let's Make a Web App, a tutorial series about
building a web app with Node. This series will
walk you through the major areas you'll need to face when building your
own applications. These tutorials are tagged with

Part 1 introduced this series and discussed how to select appropriate libraries for your Node

This part covers installing the basic tools and libraries, and we'll
also create a skeleton app and take a look at the generated code.


This project depends on the following:

I'll walk you through the installation of each of these. Refer to part
to see why I decided to
use these technologies.

Installation: Node

If you don't have Node installed download it and decompress it. I'm
using 0.2.4. You could also
use a package manager if you have one on your system. There are Debian
packages, Homebrew recipes, and more

You should be able to build and install Node like this:

make install

You may need to change the permissions of the installation directory
before running make install, or use sudo or

These steps will work for a unix-based system. If you're using Windows
you'll have to figure this part out for yourself, but running Node on
Windows is possible.


I want to use MongoDB for our database. It's also pretty easy to install
-- there are packages and compilation should be straightforward. The site has lots of binaries available.

MongoDB needs a data directory, which can be created with mkdir -p
. This is the default path, but it can be changed. I use the default on all my development machines.

The MongoDB Quickstart
is a good place
to start for more installation help.


npm makes managing Node packages quicker and easier than fetching their source. The recommended
installation method is to run a command that downloads a script and
installs npm somewhere you have permission to write.

If you're developing on your own machine, you could chown -R
\$USER /usr/local
and run curl http://npmjs.org/install.sh | sh.

Alternatively, build Node with its prefix somewhere in your
home directory:

./configure --prefix=~/local

npm will then see this and install its packages alongside Node. There
are detailed instructions in gist


Now we've got npm our required packages can be installed:

npm install express mongoose jade less expresso

Don't be put off by npm's verbosity, the messages are actually fairly
easy to follow. Just make sure it prints Success for each package.

A Basic Express App with MongoDB

When I work with Mongo, I usually start a local server. This is


It'll display the port it's using, which you needs to be noted down for
the Mongoose connection settings.

Express ships with a commandline utility for creating apps. Change to a
suitable directory and type this to generate a skeleton app:

express nodepad

The resulting code should run with node app.js. View it by
visiting http://localhost:3000.

Skeleton Analysis

The first line is standard CommonJS: the express module is
required, and the app is created and exported -- that just makes it
easier to test, don't worry if this doesn't make sense yet.

Express has changed a lot in the last year, so be careful with old
tutorials because they may use a different API. Since the initial
release, connect has been added, which is a middleware layer. This
allows certain chunks of the HTTP stack and web app framework to be
interchangeable. Configuration in particular has changed a lot.

What you should be seeing is this:

app.configure(function() {
  app.set('views', __dirname + '/views');
  app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
  app.use(express.staticProvider(__dirname + '/public'));

By default Express apps are very simple -- notice the view path is
specified, and a static file handler is set up with
staticProvider. express.bodyDecoder is just
used to decode application/x-www-form-urlencoded data --
i.e., forms. The methodOverride middleware allows Express
apps to behave like RESTful apps, as popularised by Rails; HTTP methods
like PUT can be used through hidden inputs. There has been
a lot of dispute about whether this is a good idea, which is presumably
why Holowaychuk has made it optional.

The main body of the app uses a jade template to generate HTML, and sets
a variable to pass to the template:

app.get('/', function(req, res) {
  res.render('index.jade', {
    locals: {
        title: 'Express'

This method call defines a route and corresponding HTTP verb,
GET and '/'. That means this little chunk of code won't
respond to a POST to '/'.

The last few lines are interesting because they actually check if the
app is running as the top-level module:

if (!module.parent) {
  console.log("Express server listening on port %d", app.address().port)

Again, this makes testing easier; don't worry if it seems strange.

Connecting Up MongoDB

Mongoose allows us to conveniently wrap simple classes around Mongo
collections. We need to load the library and instantiate a database
connection instance first:

mongoose = require('mongoose').Mongoose
db = mongoose.connect('mongodb://localhost/nodepad')

I've made a models file with an example model:

var mongoose = require('mongoose').Mongoose;

mongoose.model('Document', {
  properties: ['title', 'data', 'tags'],

  indexes: [

exports.Document = function(db) {
  return db.model('Document');

The models can be required in app.js, like this:

Document = require('./models.js').Document(db);

The database instance is passed, so db.model will return a
model instance based on the mongoose.model('Document', ...)
declaration. I thought putting the models in their own file would make
the Mongoose behaviour a little more opaque so the application
controller code is easier to follow.

The Templates

The generator uses Jade by default, and it
created this template:

h1= title
p Welcome to #{title}

This is similar to Haml, and it attempts to reduce the noise of HTML
templates. If you like plain HTML templates an alternative like
ejs can be used.

Running Tests

The Express generator also created a skeleton test. The tests are run by
typing expresso.

Get the Source

This is available on my GitHub account at


You should now be comfortable with installing a base Node development
environment with npm and mongo. You should also have a skeleton Express
app, and understand how it works and how to run Expresso tests.

I'll flesh out the app a little bit more next week.