A quick overview of npm

Every developer needs some sort of package manager when working on a project. npm is probably the most often used package manager by developers. It's very straightforward to use for basic purposes and in this post I will attempt to give a high level overview of the most important commands and some other useful ones.

So, what is npm?

npm is free package manager, which serves the purposes of creating, publishing and downloading packages. It also has a paid version for companies who want a private registry for their own software.

npm is both a command line tool (CLI) and a registry of software packages. Developers and enterprises create modules which other developers (or themselves if they use their private register) can download, install and eventually, use.

Installation

If you read these lines, chances are that you have npm installed on your machine.

If not, you can get it with Node.js. If you install Node, npm will also be on your machine as it’s bundled with Node.

As of writing these lines, the long term supported version of Node.js is 8.12.0 and the npm, which you get with Node, is of version 5.8.

You can upgrade to the latest version of npm (which is version 6.4.1 today) separately though:

npm install -g npm

So npm can update itself! You can read more detailed instructions on how to install npm here.

Use npm

When you need a package for your project you can decide to install the package locally or globally.

Global installations

Developers usually install CLI tools globally with the following command:

npm install -g PACKAGE_NAME

where the -g or --global flag means that the package will be installed globally. This means that the packages will be installed in the folder where Node is installed.

Globally installed packages are not restricted to a certain project and they can be used anywhere. Some packages out there recommend that they should be installed globally but I personally don’t like it as I prefer local, project related installations.

Local installations

Most projects are fine if packages installed locally.

A project is usually created by typing npm init in the terminal after we navigated to the project folder. This command will create a package.json file in the root.

The npm init -y will save you some time because you don’t need to answer the questions one-by-one when npm sets up package.json. Many times we keep pressing Enter anyway and accept the answers npm offers. With this command, the default answers will be used and the whole question-answer process will be skipped.

package.json will contain (among others) the dependencies (i.e. the packages that we need) for the project. These packages will be used in the code.

There are two main types of dependencies: normal and development.

Normal dependencies

When we install a package as a normal dependency, we do so by using the npm install PACKAGE_NAME --save or npm i PACKAGE_NAME -S commands. Both do the same but the second one is shorter.

A package installed this way will be listed in the package.json file’s dependencies object.

Development dependencies

Development dependencies are usually packages that are not needed in production. These tools are used for testing (e.g. Mocha, Chai), compiling (e.g. Babel) or bundling (e.g. Parcel or webpack).

Development dependencies can be installed using the npm install PACKAGE_NAME --save-dev or npm i PACKAGE_NAME -D and appear in the devDependencies section of package.json.

Both normal and development dependencies can be required in the same way in any modules of the project.

Install all dependencies

When a repository is cloned to the local machine, the dependencies need to be installed. It would be tiresome to go over both the dependencies and development dependencies and install them one-by-one.

The npm install command in the project folder installs all dependencies in the local node_modules folder.

By default, npm prepends the ^ symbol to the package name when writes them into the dependencies (and development dependencies) section of package.json. It means that the npm install command might install a higher minor or patch version of the package (the second and the third numbers in the package version can be greater than originally) if available.

This might not be an issue when a team works on a feature in collaboration. But if one needs to work on a project which was modified months ago, it might happen that newer versions of some packages are available and some features relying on the exact version displayed in the package.json might not work anymore.

The npm install -E command installs the exact version of the package and ignores npm’s default behaviour. This way it can be ensured that features will work as it was intended (unless they contain a bug but that’s another story).

Versions

When the npm install PACKAGE_NAME command is run, npm will look for the latest version of the package in its registry. It happens though that we will need a lower or a specified version of that package.

When the need for this arise, we can use the npm install PACKAGRE_NAME@VERSION command. For example, npm install mongoose@4.13.17 -S will install version 4.13.17 of Mongoose to the dependencies of the project folder.

This command is useful if it’s known that major changes occured in higher versions and our app is not compatible with it, or if we follow an older tutorial. This way we can ensure that the feature will work as expected.

Useful npm commands

npm comes with a bunch of great and useful commands. The list is long, so I only mention a few below.

The npm update PACKAGE_NAME command will update a package to the latest version with respecting npm’s default behaviour (like the ^ in the example above). If no package name is used, it will update all packages both in dependencies and development dependencies.

If you don’t need a package anymore or accidentally installed it (it happens!), they can be uninstalled with the npm uninstall PACKAGE_NAME command. The same works for global packages and this time we need to add the -g flag to the command.

We can quickly go to the website of the given package by typing npm home PACKAGE_NAME. For example, npm home mongoose will open up the Mongoose website in a new window of your default browser. It’s a quick way to check out something because there’s no need to manually open a browser tab and type in the address.

The npm docs PACKAGE_NAME command redirects you to the documentations of the given package (if it’s set). Often times this command will display the website and does the same as npm home.

Similarly, when you type npm repo PACKAGE_NAME, the GitHub repository of the given package will be opened in the browser window.

You don’t have to have these packages installed in the folder from where you submit the above commands.

Alternatives

A popular alternative to npm is yarn. Yarn is a great alternative to npm; it’s fast, secure and reliable. More and more developers and companies use yarn instead of npm. For example, Angular CLI uses it when creating the source files for a new project.

Another package manager in the market is pnpm, which saves the dependencies to a central place on the computer and places a link to the project’s node_modules folder. This way it doesn’t install the same package all over again in every project folder saving space on the hard disk.

There are other package managers out there but listing and comparing them to npm is beyond the scope of this post.

Conclusion

I provided a brief introduction to npm in this post, which is currently the most often used package manager.

It has many more features (including npx, which will be the topic of the next post) but I think that it’s enough for a high-level view. If the reader is familiar with npm (which is very probable), I hope that this post could help them organize what they know about npm.

Thanks for reading and see you next time.