Update transitive dependencies in npm

X @urre

Let’s say you are working with a project that has transitive dependencies that have vulnabilities. Updating the main library might not be enough. The use case for this is when there is a security vulnerability and you have to update a nested dependency otherwise your project would be vulnerable.

This should only be used as a last resource. Uou should first update your top-level dependencies and file an issue for them to update the vulnerable sub-dependencies.

Check the dependency tree

The ls command is used to list the dependency tree of a specific package in your Node.js project.

npm ls packagename

Example output:

npm ls third-package-name
myproject@0.1.0 /Users/username/path/to/myproject
├─┬ package-name@3.12.0
│ └─┬ another-package-name@4.12.0
│   └── third-package-name@9.17.0
├─┬ ...

When you perform security scans and audits with Snyk or Fossa or a similar tool, you may discover that for example third-package-name@9.17.0 has a vulnability. Updating the library or package using this transitive package is the best, but if this is not possible your could pin it like this.

Install force-resolutions

This package modifies package-lock.json to force the installation of specific version of a transitive dependency (dependency of dependency), similar to yarn’s selective dependency resolutions, but without having to migrate to yarn.

npm i -D force-resolutions

Add a resolutions key to package.json

  "resolutions": {
    "third-package-name": "^12.0.0"
  }

Where as an example 12.0.0 is the updated version that doesn’t have vulnabilities

Add an npm script to fix resolutions before your install command

"preinstall": "npx force-resolutions",

Install and update the transitive dependency

Install again

npm i

Now, when you check the dependency tree agin, you can see it has been fixed:

npm ls third-package-name
myproject@0.1.0 /Users/username/path/to/myproject
├─┬ package-name@3.12.0
│ └─┬ another-package-name@4.12.0
│   └── third-package-name@12.0.0
├─┬ ...