The Power of NPM Scripts

Npm scripts are my absolute favorite feature of npm. They're a much easier, more flexible alternative to task runners.

The Power of NPM Scripts

Npm scripts are my absolute favorite feature of npm. They're a much easier, more flexible alternative to task runners.

So, what is a npm script? A npm script is, well, exactly what the name says. It's a command-line script that is run through npm. It facilitates the use of locally installed dependencies without making them available system-wide.

This allows you to write common application routines without the need for too many configuration files. The common way to do this used to be using Gulp or Grunt, or even using bash scripts. Lately, a lot of developers are moving over to npm scripts because of how simple and flexible they are.

How to write npm scripts

When you talk about npm, you talk about package.json, of course. The package.json file has a scripts field where you define all the routines.

If you don't recall from the previous tutorial, the package.json file is your package's configuration file, generated after running npm init.

// File: package.json

{
    "name": "my-package",
    "description": "This is a sample project for the Node.js Simplified Tutorial.",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        ...
    },
    "dependencies": {
        ...
    },
    "devDependencies": {
        ...
    }
}

The part we're interested in now is the "scripts" field. That's where we define named command-line scripts that pass through npm.

Your first script

Let's go ahead and add a very simple script called hello, that writes an output to the command line terminal. To do so, write the name of the script and the command associated to it in quotes.

The script we're writing is a plain bash script:

// File: package.json

{
    ...
    "scripts": {
        "hello": "echo 'Hello npm scripts!'"
    }
}

Next, any npm script you write can be executed using the npm run command.

npm run hello

The start script

Perhaps the most popular npm script ever is the start script:

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

As you've seen above, starting a command is done using the npm run command. The start script, however, is a built-in script and we can optionally ommit the run keyword for it.

npm start

Script composition

One common use for npm scripts is as an alternative to task runners. Npm scripts make it easy for you to execute long lines using simple commands.

In my experience, one of the best things about using npm scripts is script composition. This means that npm allows you to compose large npm scripts out of multiple smaller ones, allowing you to use npm run my-script inside of another script.

Let's take a look at the dev npm script I wrote here:

{
    ...
    "scripts": {
        "start": "node index.js",
        "webpack": "webpack --config config/webpack.config.js",
        "dev": "npm run webpack && npm start"
    }
}

If you are not very comfortable with terminal commands, what you need to know is:

  • running npm scripts in series is done using a double ampersand &&, the second command executing after the successful execution of the first one.
  • running npm scripts in parallel is done using a single ampersand & (on UNIX-based systems) or the concurrently package, with the two commands executing at the same time.

Running npm run dev will run both the start and the webpack scripts I've defined above. Yup, you can do that and it's awesome!

Script execution hooks

Npm scripts have before and after script events which I call script execution hooks. They're basically other scripts that will be executed before or after the script you're running. Hooks can be added by simply prepending the pre (before) and post (after) keyword to your npm script name.

Let's say that, for example, you have a script called count. If you'd like to add a pre-execution hook to it, you would call it precount. If you'd like to add a post-execution hook, you would call it postcount. Simple, isn't it?

{
    ...
    "scripts": {
        "precount": "echo '1'",
        "count": "echo '2'",
        "postcount": "echo '3'"
    }
}

Now, when running npm run count, npm will actually execute three scripts, in the following order: precount, count, postcount. The displayed output will be 1 2 3.

Built-in npm scripts

There's a number of special scripts that npm treats differently, such as the start script you've seen above. The built-in scripts are used for basic commands, as well as for some pre (before) and post (after) script execution hooks.

Note: The built-in scripts can be executed without the run keyword.

npm start

Keep in mind that most built-in npm scripts come with a default behaviour. However, you can override the behaviour or add a custom command to be executed alongside the command's default behaviour.

  • install: Installs the package and all its dependencies.
    The built-in npm script hooks for npm install are: preinstall, postinstall
  • uninstall: Uninstalls the package.
    The built-in npm script hooks for npm uninstall are: preuninstall, postuninstall
  • start: Starts the package execution.
    The built-in npm script hooks for npm start are: prestart, poststart
  • stop: Stops the package execution.
    The built-in npm script hooks for npm stop are: prestop, poststop
  • restart: Restarts the package execution. Default runs the stop and start scripts.
    The built-in npm script hooks for npm restart are: prerestart, postrestart
  • prepare: Runs before the package is packed and published, and on local npm install without any arguments.
  • publish: Publishes the package to npm.
    The built-in npm script hooks for npm publish are: prepublish, prepublishOnly, postpublish
  • version: Runs after bumping the package version.
    The built-in npm script hooks for npm version are: preversion, postversion
  • shrinkwrap: Locks down dependency versions for publication.
    The built-in npm script hooks for npm shrinkwrap are: preshrinkwrap, postshrinkwrap
  • pack: Creates a tarball from a package.
    The built-in npm script hooks for npm pack are: prepack, postpack
  • test: Runs the tests of the package.
    The built-in npm script hooks for npm test are: pretest, posttest

I'm sure that not all of them will be useful to you, but some will be nice to know for when you're creating your own package.

What's next?

Now that you've learned about the utility of npm scripts, it's time to create your first real Node.js application.

As always, I'd love to hear your opinion about this article! Make sure to leave a comment down below.

Read up next