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.
In this guide, we’re going to look at the basics of working with npm. We’ll show you how to install packages in local and global mode, as well as delete, update and install a certain version of a package. We’ll also show you how to work with
package.json to manage a project’s dependencies. If you’re more of a video person, why not sign up for SitePoint Premium and watch our free screencast: What is npm and How Can I Use It?
But before we can start using npm, we first have to install Node.js on our system. Let’s do that now.
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 outlined here.
For this tutorial, we’re going to use v12.15.0. At the time of writing, this is the current Long Term Support (LTS) version of Node.
Tip: You might also consider installing Node using a version manager. This negates the permissions issue raised in the next section.
Let’s see where node was installed and check the version:
$ which node /usr/bin/node $ node --version v12.15.0
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 .editor Enter editor mode .exit Exit the repl .help Print this help message .load Load JS from a file into the REPL session .save Save all evaluated commands in this REPL session to a file Press ^C to abort current expression, ^D to exit the repl
The Node.js installation worked, so we can now focus our attention on npm, which was included in the install:
$ which npm /usr/bin/npm $ npm --version 6.13.7
npm, which originally stood for Node Package Manager, is a separate project from Node.js. It tends to be updated more frequently. You can check the latest available npm version on this page. If you realize you have an older version, you can update as follows.
For Linux and Mac users, use the following command:
npm install -g npm@latest
For Windows users, the process might be slightly more complicated. This is what it says on the project’s home page:
Many improvements for Windows users have been made in npm 3 – you will have a better experience if you run a recent version of npm. To upgrade, either use Microsoft’s upgrade tool, download a new version of Node, or follow the Windows upgrade instructions in the Installing/upgrading npm post.
For most users, the upgrade tool will be the best bet. To use it, you’ll need to open PowerShell as administrator and execute the following command:
Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force
This will ensure you can execute scripts on your system. Next, you’ll need to install the npm-windows-upgrade tool. After you’ve installed the tool, you need to run it so that it can update npm for you. Do all this within the elevated PowerShell console:
npm install --global --production npm-windows-upgrade npm-windows-upgrade --npm-version latest
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.
If you’re not using a version manager (which you probably should be), global packages are installed in
prefix/lib/node_modules/, which is owned by root (where
prefix is usually
/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.
Let’s change that!
Changing the Location of Global Packages
Let’s see what output
npm config gives us:
$ npm config list ; cli configs metrics-registry = "https://registry.npmjs.org/" scope = "" user-agent = "npm/6.13.7 node/v12.15.0 linux x64" ; node bin location = /usr/bin/nodejs ; 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
This is the prefix we want to change, in order 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’ve 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@latest -g
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
.bashrc and restarting your terminal:
.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 6.13.7
Tip: you can avoid all of this if you use a Node version manager. Check out this tutorial to find out how: Installing Multiple Versions of Node.js Using nvm.
Installing Packages in Global Mode
--global flag, but this can be abbreviated to
$ npm install uglify-js --global /home/sitepoint/.node_modules_global/bin/uglifyjs -> /home/sitepoint/.node_modules_global/lib/node_modules/uglify-js/bin/uglifyjs + email@example.com added 3 packages from 38 contributors in 0.259s
As you can see from the output, additional packages are installed. These are UglifyJS’s dependencies.
Listing Global Packages
We can list the global packages we’ve installed with the
npm list command:
$ npm list --global home/sitepoint/.node_modules_global/lib ├─┬ firstname.lastname@example.org │ ├── email@example.com │ ├── firstname.lastname@example.org │ ├── email@example.com │ ├── firstname.lastname@example.org │ ├── email@example.com .................... └─┬ firstname.lastname@example.org ├── email@example.com └── firstname.lastname@example.org
The output, however, is rather verbose. We can change that with the
$ npm list -g --depth=0 /home/sitepoint/.node_modules_global/lib ├── email@example.com └── firstname.lastname@example.org
That’s better; now we see just the packages we’ve installed along with their version numbers.
Any packages installed globally will become available from the command line. For example, here’s how you would use the Uglify package to minify
$ uglifyjs example.js -o example.min.js
Installing Packages in Local Mode
When you install packages locally, you normally do so using a
package.json file. Let’s go ahead and create one:
$ mkdir project && cd project $ npm init package name: (project) version: (1.0.0) description: Demo of package.json entry point: (index.js) test command: git repository: keywords: author: license: (ISC)
Press Return to accept the defaults, then press it again to confirm your choices. This will create a
package.json file at the root of the project:
"name": "project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": "test": "echo "Error: no test specified" && exit 1" , "author": "", "license": "ISC"
Tip: If you want a quicker way to generate a
package.json file use
npm init --y.
The fields are hopefully pretty self-explanatory, with the exception of
main field is the primary entry point to your program, and the
scripts field lets you specify script commands that are run at various times in the life cycle of your package. We can leave these as they are for now, but if you’d like to find out more, see the package.json documentation on npm and this article on using npm as a build tool.
Now let’s try and install Underscore:
$ npm install underscore npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN email@example.com No repository field. + firstname.lastname@example.org added 1 package from 1 contributor and audited 1 package in 0.412s found 0 vulnerabilities
Note that a lockfile is created. We’ll be coming back to this later.
Now if we have a look in
package.json, we’ll see that a
dependencies field has been added:
... "dependencies": "underscore": "^1.9.2"
npm, the Node Package Manager: A Beginner’s Guide