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, notnode_modules, sonpm cistays deterministic. - Set
keyto a prefix plushashFiles('**/package-lock.json'). - Add
restore-keyswith 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 ciGotchas
- Include
runner.osin the key; a Linux store will not restore cleanly on Windows. - A
restore-keyshit still re-downloads only what changed, so the partial cache is worth keeping.
Related guides
How to Warm the Cache on the Default Branch in GitHub ActionsGive pull requests a warm dependency cache in GitHub Actions by populating it on pushes to the default branch…
How to Reduce npm ci Time in GitHub ActionsSpeed up npm ci in GitHub Actions by combining the built-in setup-node cache with prefer-offline and skipping…