NPM CLI Tips & Tricks
Tags: webdev, tutorial, productivity, codenewbie
Published: 2021-12-27 15:44:24

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](https://docs.npmjs.com/cli/v8/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:

```sh
# 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:
```sh
<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:

```sh
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:

```sh
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`:

```sh
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:

```sh
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:

```sh
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:

```sh
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:

```sh
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:

```sh
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:

```sh
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](https://docs.npmjs.com/cli/v8/commands/npm-ci#description):

"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](https://twitter.com/felvct) or on [GitHub](https://github.com/felvct).

Happy Coding!