NPM - Node Package Manager


npm can install packages in local or global mode. In local mode it installs the package in a node_modules folder in your parent working directory. This location is owned by the current user. Global packages are installed in {prefix}/lib/node_modules/ which is owned by root (where {prefix} is usually /usr/ or /usr/local). This means you would have to use sudo to install packages globally, which could cause permission errors when resolving third-party dependencies, as well as being a security concern. Lets change that:

Changing the Location of Global Packages

Let’s see what output npm config gives us.

$ npm config list
; cli configs
user-agent = "npm/3.6.0 node/v5.7.0 linux x64"

; node bin location = /usr/local/bin/node
; cwd = /home/sitepoint
; HOME = /home/sitepoint
; 'npm config ls -l' to show all defaults.

This gives us information about our install. For now it’s important to get the current global location.

$ npm config get prefix
/usr/local

This is the prefix we want to change, so as to install global packages in our home directory. To do that create a new directory in your home folder.

$ cd && mkdir .node_modules_global
$ npm config set prefix=$HOME/.node_modules_global

With this simple configuration change, we have altered the location to which global Node packages are installed. This also creates a .npmrc file in our home directory.

$ npm config get prefix
/home/sitepoint/.node_modules_global
$ cat .npmrc
prefix=/home/sitepoint/.node_modules_global

We still have npm installed in a location owned by root. But because we changed our global package location we can take advantage of that. We need to install npm again, but this time in the new user-owned location. This will also install the latest version of npm.

$ npm install npm --global
/home/sitepoint/.node_modules_global/bin/npm -> /home/sitepoint/.node_modules_global/lib/node_modules/npm/bin/npm-cli.js
/home/sitepoint/.node_modules_global/lib
+-- npm@3.7.5

Finally, we need to add .node_modules_global/bin to our $PATH environment variable, so that we can run global packages from the command line. Do this by appending the following line to your .profile or .bash_profile and restarting your terminal.

export PATH="$HOME/.node_modules_global/bin:$PATH"

Now our .node_modules_global/bin will be found first and the correct version of npm will be used.

$ which npm
/home/sitepoint/.node_modules_global/bin/npm
$ npm --version
3.7.5

Installing Packages in Global Mode

At the moment we only have one package installed globally - that is the npm package itself. So let’s change that and install UglifyJS (a JavaScript minification tool). We use the --global flag, but this can be abbreviated to -g.

$ npm install uglify-js --global
/home/sitepoint/.node_modules_global/lib

As you can see from the output, additional packages are installed - these are uglify-js’s dependencies.

Listing Global Packages

We can list the global packages we have installed with the npm list command.

$ npm list --global
npm@3.7.5
uglify-js@2.6.2

The output however, is rather verbose. We can change that with the --depth=0 option.

$ npm list -g --depth=0
npm@3.7.5
uglify-js@2.6.2

That’s better - just the packages we have installed along with their version numbers.

At this point you can parse JavaScript files in the terminal with uglifyjs. For example the following command would minify example.js into example.min.js:

$ uglifyjs example.js -o example.min.js

Installing Packages in Local Mode

Installing packages in local mode is done without the --global flag. The package will be installed in your parent working directory in a node_modules folder. Let’s create a project folder in our home directory:

$ mkdir ~/project && cd ~/project
$ npm install underscore
/home/sitepoint/project
     underscore@1.8.3
$ ls
node_modules
$ ls node_modules
underscore

Listing Local Packages

Just like global packages we can list local packages with the npm list command.

$ npm list
/home/sitepoint/project
     underscore@1.8.3

As you can see we are able to install local packages wherever we want. This also means that we can create another directory and install a different version of underscore.

Uninstalling Local Packages

npm is a package manager so it must be able to remove a package. Let’s assume that the current underscore package is causing us compatibility problems. We can remove the package and install an older version, like so:

$ npm uninstall underscore
- underscore@1.8.3 node_modules/underscore
$ npm list
/home/sitepoint/project
     (empty)

Installing a Specific Version of a Package

We can now install the underscore package in the version we want. We do that by using the @ sign to append a version number.

$ npm install underscore@1.8.2
/home/sitepoint/project
     underscore@1.8.2
$ npm list
/home/sitepoint/project
     underscore@1.8.2

Updating a Package

The latest version of underscore fixed the bug we had earlier and we want to update our package to that version.

$ npm update underscore
underscore@1.8.3 node_modules/underscore
$ npm list
/home/sitepoint/project
     underscore@1.8.3

Note: for this to work, underscore has to be listed as a dependency in package.json (see Managing Dependencies).

Searching for Packages

We’ve used the mkdir command a couple of times in this tutorial. Is there a node package that does the same?

$ npm search mkdir
npm WARN Building the local index for the first time, please be patient

There is (mkdirp). Let’s install it.

$ npm install mkdirp
/home/sitepoint/project
+-- mkdirp@0.5.1
       minimist@0.0.8

Now create a file mkdir.js:

var mkdirp = require('mkdirp');
mkdirp('foo', function (err) {
    if (err) console.error(err)
    else console.log('Directory created!')
});

And run it from the terminal:

$ node. mkdir.js
Directory created!