How to Upgrade an npm Package's Dependencies with Yarn
4 min read
The repos I work with have Dependabot set up. For those unfamiliar with this, it's a tool that comes with GitHub that automatically identifies out of date dependencies in your repo. Depending on your configuration and type of dependency, Dependabot can also open PRs that automatically does the update for you. This is especially useful for ensuring that your app is kept up to date from a security and vulnerability perspective.
All in all, Dependabot works pretty well. There will be times however, when I'll need to do manual upgrades myself, either because there's a version mismatch between shared dependencies that cannot be resolved, or because a major / minor version upgrade is required to fix the vulnerability, and my semantic version requirement in package.json
doesn't allow for this.
So what do you do if you need to manually upgrade the dependency of your app's dependencies (i.e. your app's deep dependencies)? Before answering that, let me first take a step back for those brand new to JavaScript applications and yarn.
How does yarn and package.json work?
What you'll probably have is a package.json
file listing the npm packages (dependencies) your app uses.
If you want to upgrade your app's direct dependencies (let's say gray-matter
in this case), what you can do is run yarn upgrade gray-matter
in your command line (in the directory where your package.json
file resides). Alternatively (which tends to be what I do), amend your package.json
file with the specific version of the package you want and run yarn
. This allows me to be precise in the exact version I install (although you can also do this with the first method by running yarn upgrade [email protected]
for instance).
The first time you install your node packages for your application, you'll see a yarn.lock
file appear. This file lists out all the versions of the direct and indirect dependencies used throughout your app. Whenever the yarn
command is run, the package.json
and yarn.lock
files are compared, and missing / updated / downgraded dependencies are downloaded into the node_modules
folder.
How do you upgrade sub-dependencies?
As you won't be able to do this via package.json
, you'll need to go via the yarn.lock
file instead. Let's say we want to upgrade the mime-db
sub-dependency. In yarn.lock
, make a search for mime-db
. You'll want to find the portion of code where the package itself is defined (ignore instances where other packages reference mime-db
as a dependency to use). What you should see is mime-db@versionxxx
, along with the version, resolved link and integrity hash. You might see multiple version of mime-db, and that's fine.
To force an update, just delete all of these and run yarn
again. Note that this will only upgrade the mime-db
package to the latest minor or patch version.
What if a minor version upgrade doesn't solve the security issue?
This gets messy. What you'll essentially need to do is understand all the dependency chains that require this out of date package. You can do this by running yarn why mime-db
. For each dependency chain, you'll need to go package by package, and upgrade each one individually as needed, using the step above in the first instance.
If that doesn't work, npm provides an overrides
setting that allows you to specify which version of a package to use in a dependency tree. You can read more about configuration options here. Note that the dependency version you want might not play nicely with the existing package, so you'll be doing this at your own risk.
The ideal solution would probably be to change the package dependency at the source, by opening a pull request, with well-tested changes, so this can benefit the entire community. 😊