Yarn (and npm) were getting exceptionally slow on my system. Rather than accepting it I tried solving the underlying problem. For me the problem turned out to be the case-sensitive volume I was using.

TLDR: Set cache folder to same volume when working on other volume

The problem

Both npm and yarn commands were dreadfully slow for larger projects. I won't dive into npm here, but for yarn I noticed the linking took the bulk of the time.

The linking phase actually copies the files from the global cache dir to your local node_modules. I use a case-sensitive filesystem wherever I can. One less source of hard to pin down bugs. On top of that case-sensitivity is the team friendly option when you are sharing anything. Try changing a file casing on a case-insensitive fs in a large project to understand what I'm getting at ;).

OS X is pretty poor on the case-sensitivity front. There's a hidden option on first boot to enable it system wide. If you didn't do that, you're pretty much stuck using a case-sensitive volume that is mounted on boot.

The problem is when you use your packager on this volume. Step 2 of yarn fetches packages to yarn cache dir: /Users/name/Library/Caches/Yarn/v6. And step 3, linking, copies those packages to your project node_modules, crossing a volume boundary. This is the sluggish process.

The solution

Use a cache directory on the same volume as your project directory.

If, like me, you only use the same volume for your work then you can set the cache dir globally:

mkdir -p ~/CaseSensitiveWorkspace/caches/Yarn
yarn config set cache-folder ~/CaseSensitiveWorkspace/caches/Yarn

If you don't want a global config you can also supply a --cache-folder flag to the yarn command. Or you can set the YARN_CACHE_FOLDER env variable. See the official documentation for details.

Result

For a running large react-native project yarn add went from 180 seconds to 17 seconds. On top of that, the system didn't freeze anymore because of excessive IO. A pleasant result for such a simple fix.

yarn add package time before speedup
yarn add package time before speedup
yarn add package time improved processing time
yarn add package time improved processing time

NPM

I haven't tried it yet, but these are some of the npm commands that should help:

  • Get cache dir location: npm config get cache
  • Set cache dir location: npm config set cache --global <dir>