Sign in
Log inSign up

NPM CLI Tips & Tricks

Felix Vaucourt's photo
Felix Vaucourt
·Dec 27, 2021·

5 min read

If you are reading this, I am going on a whim and I will assume that you are using npm.

Even though, this package manager comes with a fair amount CLI commands, the chances are pretty high that you are using the same couple of ones in your day-to-day job.

You are most likely familiar with installing and deleting packages either on a global level (accessible from anywhere on your machine) or on a local level (think of the package.json in your projects).

But do you really know which and how many packages are globally installed on your workstation? To be quite honest, probably not.

Let's dive into it by listing all your global packages:

# for npm v7+
npm list -g

# for npm v6 and less
npm list -g --depth 0

hint: -g is the shorthand for --global. You can execute all of the commands below for your local packages by omitting the -g flag. And instead of using list you can use ls.

Output:

<your_user>/.nvm/versions/node/v16.13.0/lib
├── corepack@0.10.0
└── npm@8.1.0

The installation path of the displayed packages will always be printed out at the top of the list

The --depth 0 flag hides the dependencies of each installed package. Since npm v7, this is the default behavior of the npm list command.

If you wish to see all packages, including their dependencies, simply add the --all flag:

npm list -g --all

Furthermore, the depth flag isn't restricted to 0. In fact, the trailing number represents the level of nested dependencies that you want to see. If you are interested in the top-level dependencies of your global packages, you would use the following command:

npm list -g --depth 1

On a side note, if you installed a package in a custom location, using the --prefix flag, then you will need to add the same flag (including the path) when running the npm list command.

If you are looking for a specific package, either locally or globally, to check its version for example, you can combine npm list with grep:

npm list -g | grep <package>

# example
npm list -g | grep rimraf

Now that we know how to list our packages, wouldn't it be great to see if they are all up-to-date? No worries, there is a command for that as well:

npm outdated -g

Do not forget to add --depth 0 if you are using npm v6 or less

This will output what packages are outdated, what their latest available versions are and where they are installed.

Since we just talked about the outdated function, let's jump right into update.

Thankfully, npm is smart enough to update all the packages to their latest version, respecting any constraints of both the package and its dependencies.

Firstly, let's see how we can update a single package:

npm update -g <package>

# example
npm update -g @angular/cli

By omitting the package name, all packages in the specified location (global or local) will be updated:

npm update -g

That is it. This will update all your packages and install new dependencies if needed. Easy as pie.

Let's take another scenario. Imagine that you are currently developing a project and you know that you need a specific package, let's say express, and you want to see what remote versions are available to you, then you would do:

npm view <package_name> versions

# example
npm view express versions

Be aware that versions is plural. This will give you a full listing of available versions.

On the other hand, if you are only interested in the latest remote version, use:

npm view <package_name> version

# example
npm view express version

Note: version is singular here

Now that we know what package and what version we need, we can install specifically that:

npm install [-E] <package>@<version>

# example for a specific version
npm install [-E] express@4.16.4

# example for the latest version
npm install [-E] express@latest

The optional -E flag (shorthand for --save-exact) will install and save the specific version of a package rather than using npm's default range operator.

Using fixed versions within your projects is generally a good idea. In the unfortunate case that a release of a package ships with breaking changes (spoiler alert, that happened to me once - only a new minor version was released but the API of the package completely changed), this will not affect your builds. Or as we saw in recent events, some npm packages are shipped with malware or other harmful software. Being on fixed version gives you a peace of mind regarding those kind of problems.

Last but not least, if you are in need of doing a clean install of your dependencies (think of continuous integration, deployment, test platforms and so on), take usage of npm ci.

This command is also significantly faster than npm install.

I will not reinvent the wheel for this one, so the upcoming statement is straight from the official documentation:

"In short, the main differences between using npm install and npm ci are:

  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • If dependencies in the package-lock do not match those in package.json, npm ci will exit with an error, instead of updating the package-lock.
  • npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
  • If a node_modules directory is already present, it will be automatically removed before npm ci begins its install.
  • It will never write to package.json or any of the package-locks: installs are essentially frozen."

There are quite a few more CLI commands for npm out there. So it doesn't matter if you are new to npm or if you are using it for long time, mastering a tool always comes with a steep learning curve. This is especially true with CLI commands, since it is not a given to know most of the flags and to know what they are telling the underlying tool to do.

Nonetheless, I hope that with those tips & tricks, you will be able to get the most out of your npm experience. Try to keep track of your global packages and to get rid of anything that is no longer needed.

Another good tip for npm users, is the usage of npx but that is a topic for a standalone article.


If you have any questions, feel free to hit me up on Twitter or on GitHub.

Happy Coding!