7 tips to properly manage your dependencies in Node.js - Heart Internet Blog - Focusing on all aspects of the web

Before using a third-party package, you should get detailed information about it and, for example, consider the popularity, the license or known security issues. And once you’ve decided to use a package as dependency, you should continue keeping an eye on it. Check regularly that your dependencies are up to date, for instance, if there are bug fixes available and if no dependencies are missing or no longer being used.

In this article, I will show you a couple of useful tools to properly address these issues and help you manage the dependencies of your Node.js applications.

Review common information about a package

Before installing a package as a dependency of your project, use npm view to get some details about the package: this includes the current version, the license that is used, information about the dependencies of the package, a short description, maintainers and much more.

For example, to get the latest information about the “express” package, you would use the following command:

bash
$ npm view express

The information returned is formatted as JSON, which can be easily used for further processing, for example in the build process or when hooking into the preinstallation process before installing a package. While JSON is useful for that kind of automated processing, for manual checking I recommend using more specific subcommands of npm view to get exactly the information that you are interested in:

bash
# get the current version
$ npm view express version
4.16.3
# get the license of that version
$ npm view express license
MIT
# get a list of all versions available
$ npm view express licenses
[ '0.14.0',
  '0.14.1',
  '1.0.0-beta',
  '1.0.0-beta2',
  '1.0.0-rc',
  ...
# get the required version of Node.js
$ npm view express engines.node
>= 0.10.0

Check for unused and missing dependencies

When installing a dependency using npm install, the dependency is automatically saved in the configuration file (package.json) of the project. However, during the lifetime of a project it easily happens that a dependency is no longer needed, for example when it’s removed from the code, but not removed from the configuration file. On the other hand it also happens that you simply forget to add a dependency to package.json but use it within your application code.

One of the tools that can help you avoiding both scenarios is “npm-check“, which can be installed globally with the following command:

bash
$ npm install -g npm-check

Let’s create a simple project to show the usage of “npm-check”: first install a dependency that is not used in the code and then use a dependency that is not referenced in the package.json file:

bash
$ mkdir example
$ cd example
$ npm init -y
# install express but don't use it
$ npm install express
# use lodash but don't reference it
$ echo "const _ = require('lodash');" > start.js

When you now run npm-check within the root folder of that project, it gives you the following (shortened) output, which lets you easily track down both unused and missing dependencies:

bash
$ npm-check
express   πŸ˜•  NOTUSED?  Still using express?
   Depcheck did not find code similar to require('express') or import from 'express'.
   ...
lodash    😟  MISSING!  Not installed.
   😟  PKG ERR!  Not in the package.json. Found in: /start.js

Find vulnerabilities of dependencies

In April 2018 the former Node Security Platform, also known as NSP, was bought by npm, Inc. and since npm@6 it’s the base for checking security issues and vulnerabilities, which is activated by default when installing a package:

bash
$ npm install express@4.5
# ...
+ express@4.5.1
added 33 packages from 22 contributors in 3.365s
[!] 24 vulnerabilities found [54 packages audited]
	Severity: 9 low | 9 moderate | 6 high
	Run `npm audit` for more detail

If you want to disable this behaviour, you can either pass the --no-audit parameter or disable it globally via npm set audit false.

If you already have installed several packages and want to check for vulnerabilities for all of them, use npm audit, which will do this recursively for your project. As a result, you get a list of known vulnerabilities including the following information:

  • the package having the vulnerability
  • the package directly required in your package.json that includes the package as direct or indirect dependency
  • the exact path from the directly included package to the package having the vulnerability
  • a link to the Node Security Platform with further information and possible steps to fix the problem

If you want to automatically process this information, you can append the --json to the command and it will give you a JSON report. Also note that if you are using an older version of npm where npm audit is not available, you have a lot of great alternatives. Some of the most popular tools, for example, are Greenkeeper, Snyk and Retire.js.

Find and fix outdated dependencies

Node.js has a great community and a lot of packages that are continuously improved, be it improvements related to the performance, fixing of bugs or adding new features. Therefore one step of your build process should include checking for outdated dependencies. While you can manually check either the homepage of the package or the official registry, it’s easier to use the npm outdated command, which gives you a report including the following information: the name of the outdated package, the version that is used (e.g., 3.2.6), the latest version that can be installed according to the rules of semantic versioning (e.g., 3.21.2), and the latest version available (e.g., 4.16.3).

bash
# install an older version of Express:
$ npm install express@3.2
$ npm outdated
Package  Current  Wanted  Latest  Location
express    3.2.6  3.21.2  4.16.3  example

If you are looking for an alternative, check out “npm-check-updates“, which comes with a different set of commands and options.

Manage internal dependencies

One of the basic best practices for Node.js development is to structure your code in many different, small, reusable packages, each having a special purpose. The extreme form of this are micro-packages, often having only one exported function. But also without using this extreme form it can easily happen that you end up having dozens or even hundreds of packages for one project. This can get very complex if you manage every package in a separate Git repository, since you need to take care of the build process, the publishing and the deployment for each of those packages separately.

To overcome this problem, you might consider organising related packages in so-called mono repositories, or multi package repositories. The idea is quite simple: instead of having one Git repository for each package you just have one Git repository for a set of related packages. This way you can use the same scripts for organising the build, the publishing and the deployment for all of the packages. The most popular tool for managing multi package repositories is lerna.js. Initially developed as part of Babel, it’s now available as a separate tool and also used by other popular frameworks.

Check licenses for dependencies

One of the most important things to check before using a package is its license. Does it fit the project that are you developing? Does it restrict the usage of the package? Is there a license at all? Or is it a custom license that you need to understand first?

A nice tool which gives you an overview of all the licenses in your dependency tree is “license-checker“, which you can install globally using the following command:

bash
$ npm install -g license-checker

If you keep the information in the JSON format for further processing, you can append the parameter --json. If you are just interested in an overview, use the parameter --summary instead:

bash
$ license-checker --summary
β”œβ”€ MIT*: 15
β”œβ”€ MIT: 3
β”œβ”€ UNKNOWN: 2
β”œβ”€ Custom: https://secure.travis-ci.org/shtylman/node-cookie.png: 1
└─ ISC: 1

If you are not sure whether a given license is suitable for you, have a look at choosealicense.com/licenses/, which gives you a nice and understandable overview of several licenses and how they differ.

Keep your dependencies private

If you want to keep your packages or dependencies private, you have different options: you can use private Git repositories, use scoped packages at the official npm registry or you can use your own npm registry. The latter can be useful for different reasons, for example due to limited access to the internet, for caching packages or when using modified versions of a package.

One popular example for a private npm registry completely written in JavaScript is Verdaccio, a Fork of the former sinopia. It’s available via npm and as a Docker image provided at Docker Hub.

There is more…

In this article I showed you some useful tools for managing your dependencies. But there is more. For example, if you are developing many different packages in parallel that depend on each other, it’s useful to use npm link to create symbolic links, so that changes in one package immediately become visible in other packages. And last but not least: keep your own packages up to date, so that others can get the information they are looking for when they want to use them.

Subscribe to our monthly Heart Internet newsletter, filled with the latest articles about web design, development, building your business, and exclusive offers.

Subscribe now!

Comments

Please remember that all comments are moderated and any links you paste in your comment will remain as plain text. If your comment looks like spam it will be deleted. We're looking forward to answering your questions and hearing your comments and opinions!

Leave a reply

Drop us a line 0330 660 0255 or email sales@heartinternet.uk