Best Practices for Node.js Development

Last Updated: 01 October 2014

javascript node npm

Table of Contents

For most of the nearly twenty years since its inception, JavaScript lacked many of the niceties that made other programming languages like Python and Ruby so attractive: command-line interfaces, a REPL, a package manager, and an organized open-source community.

Thanks in part to Node.js and npm, today’s JavaScript landscape is dramatically improved. Web developers wield powerful new tools, and are limited only by their imagination.

What follows is a list of tips and techniques to keep you and your node apps happy.

This material is a curated and maintained version of a blog post on the same topic.

Start new projects with npm init

npm includes an init command which walks you through the process of creating a package.json file. Even if you’re intimately familiar with package.json and its properties, npm init is a convenient way to get your new node app or module started on the right track.

It sets smart defaults for you, like inferring the module name from the parent directory name, reading your author info from ~/.npmrc, and using your git settings to determine repository.

$ mkdir my-node-app
$ cd my-node-app
$ npm init

Declare all dependencies

It’s good to get in the habit of using --save (or --save-dev) every time you install a module that’s local to your project. These flags add the given module to your package.json’s dependencies (or devDependencies) list and use a sensible default semver range.

$ npm install domready --save

Notice that npm now uses caret-style semver ranges:

"dependencies": {
  "domready": "^1.0.4"

Specify a start script

Setting a value for scripts.start in package.json allows you to start your app on the command line with npm start. This is a great convention to follow, as it allows any node developer to clone your app and get it running easily without any guesswork.

Bonus: If you define scripts.start in your package.json file, you don’t need a Procfile. A Procfile will be created automatically using npm start as the web process type.

Here’s an example start script:

"scripts": {
  "start": "node index.js"

Specify a test script

Just as anyone on your team should be able to run your app, they should also be able to test it. The scripts.test field in package.json is used to specify the script to run your test suite. If you’re using something like mocha to run tests, be sure to include it in devDependencies in package.json, and refer to the binary that’s local to your project, rather than the mocha you have installed globally:

"scripts": {
  "test": "mocha"

Keep dependencies out of source control

Many node apps use npm modules with C dependencies like bson, ws, and hiredis that must be compiled for Heroku’s 64-bit Linux architecture. This compilation step can be a time-consuming process. To keep builds as fast as possible, Heroku’s node buildpack caches dependencies after they’re downloaded and compiled so they can be re-used on subsequent deploys. This cache means reduced network traffic and fewer compiles.

Ignoring the node_modules directory is also the npm recommended practice for module authors. One less distinction between apps and modules!

$ echo node_modules >> .gitignore

Use environment variables to configure npm

From the npm config docs:

Any environment variables that start with npm_config_ will be interpreted as a configuration parameter. For example, putting npm_config_foo=bar in your environment will set the foo configuration parameter to bar. Any environment configurations that are not given a value will be given the value of true. Config values are case-insensitive, so NPM_CONFIG_FOO=bar will work the same.

The app environment is available in all Heroku builds. This gives node users on Heroku control over their npm configuration without having to make changes to application code.

Bring your own npm registry

The public npm registry has seen immense growth in recent years, and with that has come occasional instability. As a result, many node users are seeking alternatives to the public registry, either for the sake of speed and stability in the development and build cycle, or as a means to host private node modules.

A number or alternative npm registries have popped up in recent months. Nodejitsu and Gemfury offer paid private registries, and there are some free alternatives such as Mozilla’s read-only S3/CloudFront mirror and Maciej Małecki’s European mirror.

Configuring your Heroku node app to use a custom registry is easy:

heroku config:set npm_config_registry=

Keep track of outdated dependencies

If you’ve been programming long enough, you’ve probably been to dependency hell. Fortunately Node.js and npm have set a precedent for sane dependency management by embracing semver, the Semantic Versioning Specification. Under this scheme, version numbers and the way they change, convey meaning about the underlying code and what has been modified from one version to the next.

npm has a litte-known command called outdated. Combined with npm update, it’s a great tool for figuring out which of your app’s dependencies have fallen behind and need to be updated:

$ cd my-node-app
$ npm outdated

Package            Current  Wanted     Latest  Location
-------            -------  ------     ------  --------
express              3.4.8   3.4.8  4.0.0-rc2  express
jade                 1.1.5   1.1.5      1.3.0  jade
cors                 2.1.1   2.1.1      2.2.0  cors
jade                0.26.3  0.26.3      1.3.0  mocha > jade
diff                 1.0.7   1.0.7      1.0.8  mocha > diff
glob                 3.2.3   3.2.3      3.2.9  mocha > glob
commander            2.0.0   2.0.0      2.1.0  mocha > commander

If you’re working on open-source node apps or modules, check out david-dm, NodeICO, and, three great services that provide graphical badges you can use to display live dependency info on your project’s README or website. Also, the versioneye service can integrate with GitHub to notify you when libraries grow out-of-date.

Use npm scripts to run custom build steps

As the npm ecosystem continues to grow, so do the options for automating the development and build process. Grunt is by far the most popular build tool in the node world today, but new tools like gulp.js and plain old npm scripts are also attractive options with lighter footprints.

When you deploy a node app to Heroku, the npm install --production command is run to ensure your app’s npm dependencies are downloaded and installed. But the command does something else too: It runs any npm script hooks that you’ve defined in your package.json file, such as preinstall and postinstall. Here’s a sample:

  "name": "my-node-app",
  "version": "1.2.3",
  "scripts": {
    "preinstall": "echo here it comes!",
    "postinstall": "echo there it goes!",
    "start": "node index.js",
    "test": "tap test/*.js"

These scripts can be inline bash commands or they can refer to command-line executables. You can also refer to other npm scripts from within a script:

  "scripts": {
    "postinstall": "npm run build && npm run rejoice",
    "build": "grunt",
    "rejoice": "echo yay!",
    "start": "node index.js"

Try new things

Harmony is the working name for ES6, the next edition of the ECMAScript language specification commonly known as JavaScript. Harmony brings lots of exciting new features to JavaScript, many of which are already available in newer versions of node.

Harmony enables many new features like block scoping, generators, proxies, weak maps, etc.

To enable harmony features in your node app, specify a newer node engine like 0.11.x and set the --harmony flag in your start script:

  "scripts": {
    "start": "node --harmony index.js"
  "engines": {
    "node": "0.11.x"


Client-side JavaScript has a spaghetti-code legacy, but the language itself is not to blame. The lack of a legitimate dependency manager is what kept us in the jQuery-plugin copy-paste dark ages for so many years. Thanks to npm, we’re entering the front-end renaissance: the npm registry is growing like crazy, and the proliferation of modules designed to work in the browser is staggering.

Browserify is an amazing tool that makes node modules work in the browser. If you’re a front-end developer, browserify could change your life. Maybe not today, and maybe not tomorrow, but soon. To get started using browserify, check out the articles.

What are your habits?

Whether you’ve been developing in node for a while or are just getting started, we hope you find these tips useful.