Skip to content
Latchkey

How to Choose Between Caching node_modules and the Package Manager Store

Cache the package manager download store and run a clean install; caching node_modules directly risks stale or platform-specific binaries.

The download store (~/.npm, the yarn cache, the pnpm store) holds tarballs that are portable and reused by a clean install. node_modules holds compiled, resolved output that can break when the runner OS or Node version changes, so most workflows cache the store and let npm ci rebuild.

Steps

  • Prefer caching the store path for your package manager.
  • Key on runner.os plus the lockfile hash so native builds stay valid.
  • Run npm ci (or the equivalent) rather than restoring node_modules wholesale.

Store paths

Terminal
# npm      -> ~/.npm
# yarn v1  -> $(yarn cache dir)
# pnpm     -> $(pnpm store path)

Workflow

.github/workflows/ci.yml
steps:
  - uses: actions/cache@v4
    with:
      path: ~/.npm
      key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
  - run: npm ci

Gotchas

  • A node_modules cache built on one OS can carry native addons that segfault on another.
  • If you must cache node_modules, include the Node version in the key.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →