Yarn (and npm) were getting exceptionally slow on my system. Rather than accepting the ever longer install times, 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 the same volume when working on another 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 that 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. For me the global directory is different from the volume where I keep my projects. I use a case-sensitive filesystem wherever I can - one less source of hard-to-pin-down bugs. On top of that, a case-sensitivity is the team-friendly option when you are sharing anything. Try changing a file casing on a case-insensitive filesystem 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 improved processing time

NPM cache

NPM of course has the same problem. While I haven't looked into NPM specifically, I'm sure the solution is similar. The following commands should help:

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