A Beginner's Guide to npm — the Node Package Manager

Originally published at: http://www.sitepoint.com/beginners-guide-node-package-manager/

Node.js makes it possible to write applications in JavaScript on the server. It’s built on the V8 JavaScript runtime and written in C++ — so it’s fast. Originally, it was intended as a server environment for applications, but developers started using it to create tools to aid them in local task automation. Since then, a whole new ecosystem of Node based tools (such as Grunt and Gulp) has evolved to transform the face of front-end development .

To make use of these tools (or packages) in Node.js we need to be able to install and manage them in a useful way. This is where npm, the node package manager, comes in. It installs the packages you want to use and provides a useful interface to work with them. But before we can start using npm, we first have to install Node.js on our system.

Installing Node.js

Head to the Node.js download page and grab the version you need. There are Windows and Mac installers available, as well as pre-compiled Linux binaries and source code. For Linux, you can also install Node via the package manager, as is outlined here.

To verify that your installation was successful let’s give Node’s REPL a try.

$ node
> console.log('Node is running');
Node is running
> .help
.break Sometimes you get stuck, this gets you out
.clear Alias for .break
.exit  Exit the repl
.help  Show repl options
.load  Load JS from a file into the REPL session
.save  Save all evaluated commands in this REPL session to a file
> .exit

The Node.js installation worked, so we can now focus our attention on npm, which was included in the install.

$ npm -v
1.4.28

Node Packaged Modules

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
registry = "https://registry.npmjs.org/"
user-agent = "npm/2.6.0 node/v0.10.36 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
npm@2.6.0 /home/sitepoint/.node_modules_global/lib/node_modules/npm

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 -v
2.6.0

Continue reading this article on SitePoint

You should probably mention that it’s incredibly buggy on Windows and they have no intention of fixing this. This includes operating within virtual machines, so if you have a Linux VM with folders shared to your Windows host, it still fails.

As far as the JS world goes, they have volumes to learn from PHP’s package management approach.

Yeah, that kind of sucks. Reading that thread, it seems the solution they have settled on is having npm dedupe at install time, which they say is coming in v 1.5 or 1.6 (so still some way off).
There are a couple of packages you can install to do this for you in the meantime, such as npm-dedupe or npm-flatten, but admittedly this is not the most elegant solution.
Personally, I’m on Linux. I used Windows for a long time, but things like this just kept biting me, so I made the switch and frankly haven’t looked back.

Or Ruby’s.

For avid gamers like myself, that’s just not an option. I do recognize the need for a separate work machine with a proper environment, though - that’s been a constant pain ever since I transitioned into full time freelance waters.

Dual boot? Skyrim is the one thing I miss from Linux, although there are mad people out there that make it work on Wine.

Seriously though, I remember dev work being a PITA on Windows. For example, for Ruby you had to install some kind of special Windows dev kit just to create a sane build environment, then random gems would just fail to install citing a lack of headers or whatever.

I still quite often encounter sizeable projects (such as rbenv or RVM) that simply refuse to consider supporting Windows. In that respect, hats off to npm for even trying.

I develop exclusively in VMs, so no such problems here. Everything but Node works perfectly, so I’ve completely discarded that environment and stopped trying.

The friendship between me and Linux has long expired, and I can no longer bear to look at it. It’s been the source of more grief than I care to admit, far more hours wasted debugging the OS than developing (though, admittedly, it’s been two years). Seeing as I’m currently building a new gaming rig, I think my next work machine will be a Macbook of some kind so I isolate those two contexts properly, but I think we’re drifting off topic now : )

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.