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.
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@example.com 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
yarn.lock files are compared, and missing / updated / downgraded dependencies are downloaded into the
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. 😊