Post

Use Yarn Why to discover why your project has a specific dependency

When doing web development there are many occasions when I don’t know why an application has a dependency on a particular npm library that is not directly referenced in the package.json file but I need to find out. There may be a error message or a warning in the terminal for that library or perhaps a library has been flagged as a security vulnerability needing further investigation. This is where the “yarn why” comes in.

Yarn Why

‘Yarn why’ is really useful when you need to figure out why a particular package has been installed in your project. Run ‘yarn why’ passing in the package name as an argument and it will output the reasons why this package has been installed, for example as a dependency directly referenced or perhaps as a dependency that is it referenced by other packages that you directly dependent on.

yarn why package-name

Example Usage

For example, if we run ‘yarn why eslint’ on a project that has eslint directly referenced you get something like this…

yarn why eslint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yarn why v1.22.19
[1/4] Why do we have the module "eslint"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "eslint@7.32.0"
info Has been hoisted to "eslint"
info Reasons this module exists
   - Specified in "devDependencies"
   - Hoisted from "react-scripts#eslint"
info Disk size without dependencies: "4.46MB"
info Disk size with unique dependencies: "13.03MB"
info Disk size with transitive dependencies: "17.26MB"
info Number of shared dependencies: 83

This tells us that the eslint is directly referenced as a dependency in our devDependencies.

More often though the package is a dependency of another package, so for example running ‘yarn why lodash’ on a sample project that doesn’t directly reference lodash will output something like this…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ yarn why lodash
yarn why v1.22.19
[1/4] Why do we have the module "lodash"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "lodash@4.17.21"
info Reasons this module exists
   - "@testing-library#jest-dom" depends on it
   - Hoisted from "@testing-library#jest-dom#lodash"
   - Hoisted from "react-scripts#webpack-manifest-plugin#lodash"
   - Hoisted from "react-scripts#eslint-plugin-flowtype#lodash"
   - Hoisted from "react-scripts#html-webpack-plugin#lodash"
   - Hoisted from "react-scripts#@babel#core#lodash"
   - Hoisted from "react-scripts#webpack-dev-server#http-proxy-middleware#lodash"
   - Hoisted from "react-scripts#html-webpack-plugin#pretty-error#lodash"
   - Hoisted from "react-scripts#optimize-css-assets-webpack-plugin#last-call-webpack-plugin#lodash"
   - Hoisted from "react-scripts#webpack-dev-server#portfinder#async#lodash"
   - Hoisted from "react-scripts#eslint-plugin-testing-library#@typescript-eslint#experimental-utils#@typescript-eslint#typescript-estree#lodash"
   - Hoisted from "react-scripts#html-webpack-plugin#pretty-error#renderkid#lodash"
   - Hoisted from "react-scripts#jest#@jest#core#jest-config#jest-environment-jsdom#jsdom#whatwg-url#lodash"
info Disk size without dependencies: "4.86MB"
info Disk size with unique dependencies: "4.86MB"
info Disk size with transitive dependencies: "4.86MB"
info Number of shared dependencies: 0

So we can see @testing-library#jest-dom” depends on it, and also that the package is hoisted (i.e. shared among multiple dependencies). This information can be really useful during investigations.

For more info check out the Yarn docs here: https://yarnpkg.com/cli/why

This post is licensed under CC BY 4.0 by the author.