Speed up your CI and DX with node_modules/.cache

You may not need to cache your entire node_modules

Jongleberry
2 min readSep 7, 2021

node_modules/.cache is a community-standard cache folder for storing files. Many projects such as ava, nyc, storybook, and many webpack loaders and plugins use this folder by default. With some configuration, you can speed up your CI and developer experience by pointing other caches to this folder and persisting it across builds.

GitHub Actions Setup

Here’s an example GitHub Action that caches node_modules/.cache, creating a new cache value after every run with the suffix -run-id-${{ github.run_id }}. This is in contrast to the node_modules cache that relies strictly on the hash of the manifest files. In other words, the node_modules cache should only change when the manifest changes, but the node_modules/.cache cache should be constantly updated.

Use node_modules/.cache for your commands

Here are some commonly used modules and how to set up their cache directories:

  • jest: set cacheDirectory: 'node_modules/.cache/jest' in your config
  • stylelint: run with --cache --cache-location=node_modules/.cache/stylelint
  • eslint: run with --cache --cache-location=node_modules/.cache/eslint
  • babel-loader: set cacheDirectory: 'node_modules/.cache/babel-loader in your config

With these cache directories set up, I have experienced subsequent test and lint runs take a fraction of the time, both locally and on CI. I’ve been able to eliminate a lot of workarounds with this performance gain such as hooks that only lints changed files.

Consider caching node_modules/.cache instead of node_modules

When set up properly, you may only need to set up caching on the .cache folder, especially if your npm ci runs very fast.

Some reasons you may not want to cache your entire node_modules folder are:

  • On a self-hosted runner, you can rely on npm's caching mechanism, which already caches package tarballs on the runner (actions do not run in isolation, so they will have access to this folder)
  • Self-hosted runners will probably have a weaker connection to the cache store, making the cache slower
  • node_modules tends to become large and each GitHub repository has a cache limit (currently 5GB), so caching your node_modules may evict your other caches sooner

Here are some cases you may still want to cache your node_modules:

  • Your node_modules folder is very large and caching is significantly faster than running npm ci
  • You have a lot of postinstall build scripts, e.g. binaries that need to be compiled

My recommendation is to start with just caching node_modules/.cache, then check whether caching node_modules as well will speed up your CI.

--

--

Responses (1)