Qubyte Codes

Tip: customizing npm version


The npm CLI has a bunch of useful utilities for managing projects. The obvious one is npm test but there are others. I particularly like working with npm version (the subject of this tip).

Without customization, npm version checks that the working git directory is clean, sets the new version in the package file, and then commits it and tags the repository with the same new version.

That's great, but what if you have a bower.json file, or some other task which needs the new version before the tag is made? npm version updates the version in package.json and it misses the version in the bower.json file. The bower.json version is just an example, but one that illustrates this point.

This is where customizing npm version comes in. Continuing the bower.json example, we can write a script which performs the version update, and uses git add on it. In the package.json file:

  "name": "my lovely app",
  "version": 1.0.0,
  "scripts": {
    "version": "node update-bower-version.js && git add bower.json"

To reiterate, npm version will update the version in the package file, run the version script above, and then commit the changes and tag the result. That means that the script needs to do something to the bower.json file, then git add the result.

// update-bower-version.js

var fs = require('fs');
var bowerJsonPath = require.resolve('./bower');
var bowerJson = require(bowerJsonPath);

bowerJson.version = process.env.npm_package_version; // npm injects this

fs.writeFileSync(bowerJsonPath, JSON.stringify(bowerJson, null, 2));

This script is going to be run by npm from the package.json file, which handily injects some environment variables. One of these variables is the version in the package.json file. This is great because it means that no matter what the new version will be we have access to it in this script.

Since the bower.json file contains JSON it can be read and parsed by require in one step. The version is updated, and the result stringified (I'm using two space indentation here) and written back to the bower file.

With a script in place, you can use npm version without further thought. for example, a major version bump looks like:

npm version major