Skip to content
Latchkey

How to Cache node_modules by Lockfile Hash in GitHub Actions

A cache key built from the lockfile hash hits exactly when dependencies are unchanged and falls back via restore-keys when they shift.

Key actions/cache on hashFiles('**/package-lock.json') so the key changes only when the lockfile does, and add a stable restore-keys prefix so a partial match still seeds the store before npm ci.

Steps

  • Cache ~/.npm, not node_modules, so npm ci stays deterministic.
  • Set key to a prefix plus hashFiles('**/package-lock.json').
  • Add restore-keys with the bare prefix for partial-hit fallback.

Workflow

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

Gotchas

  • Include runner.os in the key; a Linux store will not restore cleanly on Windows.
  • A restore-keys hit still re-downloads only what changed, so the partial cache is worth keeping.

Related guides

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