Start a new Node.js Express app the right way

Matthew Nuzum —  — 11 Comments

Node.js is extremely popular and no doubt you’ve seen some amazing work being done with it. Getting started can be tricky because of a few things: Node.js is a flexible, powerful tool that can be used to build many different types of projects, from server applications, to websites, to utilities. Also, because it is still an emerging tool with an explosive rate of growth, there are many ways to do the same thing and it’s hard to tell what tools and processes to use.

One thing that has stabilized in the Node.js web development community is that two libraries that are often used to build new web apps are connect and express. Connect is a low-level utility that lets you speak http and other network protocols. Express make it easier to build great websites and builds on top of Connect.

I’m going to show you a couple tricks I’ve found that will help you get started with Express and hopefully speed up how you build web apps with Node. I’ll use this tutorial as a launching point for other tutorials I’m publishing as well. I’m not going to try very hard to make this short, rather I’ll try to help you understand the process well.

When we’re done we’ll have an express app with Less, sessions, a test runner and auto-reloading of files when they change. Before you proceed, ensure you have Node.js and npm installed.

Update: Check out an even better template option for Express apps.

We’ll begin with npm, the Node package manager tool. When you installed Node.js you probably also received npm at the same time. I mentioned that Express is a stable aspect of the Node.js community, well npm is even more stable, and it will be rare to find a project that doesn’t rely on it.

Whenever you create a project, you’ll create a file called package.json which will describe your project and more importantly help npm install your project’s dependencies. As you might expect, a project that uses Express will depend on the Express npm module.

When you install a library with npm it is installed into the project you’re working on, into a folder called node_modules. If you have two projects and install express in one, that does not mean you will be able to use it in the other project. Each keeps their modules isolated from each other. The Ruby and Python communities both went through trying periods because, for the early parts of their existences, they didn’t have such tools. The Node community seems to have learned from the challenges others have faced and planned from the beginning to avoid them.

There is a way to install node modules system wide, however. Instead of making a package.json, we’ll instead install the package specifically from the command line. We’ll do this now and install express so that we can use it’s command line utilities later on.

To do this, from your console where you access npm, use this command:

npm install -g express

If you are on Mac or Linux and get a permission denied error, then instead use sudo npm install -g express. That will prompt you for your password so that the tool can install the package. If you were prompted here then you’ll always have to use sudo when you use -g.

So what does -g do? It installs the package globally. If you hadn’t used -g then you’d find that in the folder you’re in, you’ll see a newly created node_modules folder and it would be installed there.

I learned this the hard way when I was preparing for a flight and a few hours of working offline. I downloaded all the tools I thought I’d need but didn’t use -g. To this day I don’t know what folder I was in but needless to say, I ended up just reading a book during that flight. 🙂

Now that we have express installed globally we can create a new project. Make a folder and, using your terminal, change to that new folder. You should be inside of the folder. For example:

Mac/Linux/Windows:

mkdir ExpressProject; cd ExpressProject

Now that you’re in your new folder, we’ll use the express command to turn it into an Express project.

Type express -h and press enter to see a list of options. If you’d just typed express and pressed enter, you’d have a new project with the default values.

The values I use are:

express -s -H -c less

Before you use that, let me tell you what you get with that:

A very popular option instead of -H is to use Jade, which happens to be the default. So if you don’t use -H or -e (ejs) or -J (JSHtml) then you’ll get Jade. The tutorials I use on my site will be based on Hogan.js.

If you like CSS but wished it were a little more powerful, then Less is a great option. Just write your CSS as you normally would but give it a .less extension, the app will automatically convert it to CSS for you. Then, as you’re ready, you can begin using variables and mixins to make your styles more powerful.

If you don’t like CSS and wish your styles looked a little more like Python or Ruby, then you might prefer -c stylus to add Stylus support//learnboost.github.io/stylus/”>Stylus support. The tutorials on this site will be utilizing Less or plain CSS.

If the folder you’re in is not empty, then using the express command will cause an error. It may ask you if you want to proceed, and it will overwrite any files that are duplicated. You can say “yes” or “no” as you see fit.

Now that we have a skeletal express app, we need to install the dependencies. Type npm install and watch the screen fill up with modules being downloaded and installed. You may see warnings, you can ignore these. If you see errors, npm will stop.

Now we can run our test app and ensure the pieces are working. Type npm start to begin.

If you are in Windows, you may see an alarming message from your firewall that looks like this:

e5b12b50-538a-47bf-9cf7-11d7a7ae5ab3

I’d suggest leaving the top option checked and pressing “Allow access”. If you don’t do this, then you will be unable to easily develop locally. If you often work in coffee shops and airports and want to show others your work, or maybe test from a mobile device while on such a network, then you may want to enable the second checkbox as well.

Whatever OS you use, after this you should see a message that the Express server is listening on port 3000. Visit http://localhost:3000/ to see your new app. Note that with Internet Explorer you must have the http:// at the beginning. Also, if you are using IE you may see this alert:

4daae001-35d3-4243-bf36-dcab0306fa5a

I choose “Yes” because I want to have more access. I trust the code I run locally.

Now you should see a mostly blank web page that says “Express, Welcome to Express”

Now let’s start customizing things. Don’t worry, it’s easy!

Back in your terminal, press ctrl+C to terminate the Node.js server. Now, using a code editor such as Sublime Text, Notepad++, gEdit or Text Wrangler, open package.json. As the file extension may indicate, this is a Json document. It looks like Javascript. Note the section that controls dependencies:

  "dependencies": {
    "express": "3.2.6",
    "hjs": "*",
    "less-middleware": "*"
  }

What we need to do is add a couple things here to get our app just right. Particularly, we’re going to add code for a test runner and auto-reloading of our app when we make changes.

We’re going to add these lines before express:

        "mocha": "*",
        "chai": "*",
        "sinon": "*",
        "supervisor": "*",

So the end result should look like this:

    "dependencies": {
        "mocha": "*",
        "chai": "*",
        "sinon": "*",
        "supervisor": "*",
        "express": "3.x",
        "hjs": "*",
        "less-middleware": "*"
    }

Please note that every line must end with a comma except the last line. Once you do this, save your changes and exit your editor.

Back at your terminal, install the new dependencies using npm install. Wait again as all your new dependencies load.

What we’ve installed is supervisor, which is a Node.js launcher that watches your project for file changes, and when they change, it reloads your local server. This is a huge benefit when you’re frequently changing things and previewing the results. However, if you are working on an app that requires storing information in-memory, be forewarned that when it restarts your app it probably flushes the memory too!

We’ve also installed the Mocha test runner, the chai assertion library and the sinon mocking/stubbing library. These will help you test your code.

Let’s test these new features out. We’ll start with supervisor.

Mac/Linux: ./node_modules/.bin/supervisor app.js

Windows: node_modules\.bin\supervisor app.js

You should see your “Express server listening on port 3000” message again. Check it in your browser and ensure it’s working.

Assuming it is, let’s make this the default, edit your package.json again and note the “scripts” section. Right now it looks like this:

  "scripts": {
    "start": "node app.js"
  },

Take the command you used above and put it inside the quotes. Note that windows users will have to add an extra \. You’ll end up with results like this:

Mac/Linux:

  "scripts": {
    "start": "./node_modules/.bin/supervisor app.js"
  },

Windows: (note the double \\)

  "scripts": {
    "start": "node_modules\\.bin\\supervisor app.js"
  },

Now save and exit, back in your terminal type npm start to see it launch your app.

Great, let’s make some tests. Make a folder called test and in it a new file called test.js. Editing that file with your code editor, let’s add this code:

var assert = require('chai').assert;
var routes = require('../routes');

suite('Routes', function() {
     test("index route is defined", function() {
          assert.isDefined(routes.index);
     })
})

Now save and close your document. Test it by running:

Mac/Linux: ./node_modules/.bin/mocha -u tdd

Windows: node_modules\.bin\mocha -u tdd

You should see a green message saying 1 passing.

Let’s make life a little easier, edit your package.json and find the “start” line and duplicate it. Make sure to put a comma at the end of the first line. Change the second option from “start” to “test” and then use the command above inside the quotes. Here is what you should have:

Mac/Linux:
  "scripts": {
    "start": "./node_modules/.bin/supervisor app.js",
    "test": "./node_modules/.bin/mocha -u tdd"
  },

Windows: (note the double \\)

  "scripts": {
    "start": "node_modules\\.bin\\supervisor app.js",
    "test": "node_modules\\.bin\\mocha -u tdd"
  },

Now save and exit, let’s run the tests with npm test. You should get the same results.

What we did is create a test folder and in it, created a test file with a single test suite, and in that suite, a single test. Then we updated npm to tell it what to do when we use the test command.

If you like, you can enable “watch” support by adding a -w to the end. This will cause it to re-run the tests every time a file changes.

A little note that the chai library supports three different assertion frameworks. I prefer the jUnit style TDD assertions. Some people prefer the BDD style assertions and others prefer the expect style. The choice is yours.

At this point, nothing is stopping you. You can edit your routes/index.js to add some custom behavior to your homepage, or you can drop static files into the public/ folder and serve them directly. For example, try creating a new html file and saving it as public/new.html, then visit http://localhost:3000/new.html and voila!

Don’t forget your tests. You can add more tests to the existing suite or you can create new files with additional test suites.

Update: Before you go too much further, check out an even better template option for Express apps.

For reference, here is my final package.json file. This is the Windows example:

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node_modules\\.bin\\supervisor app.js",
    "test": "node_modules\\.bin\\mocha -u tdd"
  },
  "dependencies": {
        "mocha": "*",
        "chai": "*",
        "sinon": "*",
        "supervisor": "*",
        "express": "3.x",
        "hjs": "*",
        "less-middleware": "*"
  }
}
If it helped, please share!Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+

Matthew Nuzum

Posts Twitter Facebook

Web guy, big thinker, loves to talk and write. Front end web, mobile and UX developer for John Deere ISG. My projects: @dsmwebgeeks @tekrs @squaretap ✝
  • Daniel

    Thanks for the post… it had sufficient information to get understanding but not too much to get long. 🙂

    One minor correction: Since the instructions did not say that we have to go out of the tests folder, you need to use 2 dots to get to the root level in the following command:
    ./node_modules/.bin/mocha -u tdd

    • Daniel

      ah never mind… the folder name was supposed to be test, not tests. My bad 🙂

  • felipekm

    Google Translator Brazilian Detected

  • Jesus

    Heh I agree with Daniel, good basic underlying test suite tutorial, thanks

  • Jesús Mur

    Great tutorial, I’m doubting between use Moustache or Jade as motor template.

    • newz2000

      Glad you like it. I’ve actually written up several articles here on this website comparing all the popular template languages. I’m actually in the process of switching from Mustache to Handelbars.js. Handlebars is Javascript only, but for Node.js projects, that is fine. You can use them client side or server side. Jade is pretty good too, the templates come out looking very clean, but I really like HTML and Jade abstracts that away.

      • Jesús Mur

        I have been reading your post about the comparative of both motors, In one hand I like Jade because is like Python, with indentation. But in the other hand I like to write pure HTML. I’m very confused 🙂

        • newz2000

          I hear you! If in doubt, you have to fall back to less important deciding factors. Does your preferred editor work better with one or the other? Do you want to use the same template engine server and client side? They’re both great.

  • Jeff F. Panasuik

    One feedback if I may offer —

    Instead of having to do this command line to create a new project:

    $ mkdir newsite
    $ cd newsite
    $ express -s -H -c stylus

    I usually do this line as it’s dirty fast in doing the job making the directory and configuring it by only one line:

    $ express newsite -s -H -c stylus && cd newsite

    • newz2000

      Agreed, I’m definitely in support of this. In documentation I use the individual commands on their own line because it’s easier for people to read and understand. Thanks for the tip!

  • cgarveyie

    As of today Express doesn’t configure the installation properly so you’ll need to update app.js directly by changing line 25 to:
    app.use(require(‘less-middleware’)(path.join(__dirname, ‘public’)));