Skip to main content
Reuse downloaded packages and completed builds so your checks finish sooner. Save package downloads and build results separately. Compare the complete job duration to find which saves the most time for your project. First complete the CI quickstart for your repository. The examples use Linux runners and Node.js 22. Keep action versions aligned with your repository’s update policy.

Cache npm downloads

Commit package-lock.json, the lockfile that records your exact dependency versions. For a project with an npm test command, save this workflow as .github/workflows/npm-tests.yml:
.github/workflows/npm-tests.yml
The setup action saves npm’s downloaded packages. npm ci uses your lockfile to create node_modules, the directory of installed dependencies. Keep the install step on every run. It reuses saved downloads on a cache hit and downloads packages on a cache miss. Saving npm’s download cache fits this workflow because npm ci creates a fresh installed directory each time. To check reuse, run the workflow twice with the same lockfile. Look for a restore message in the setup action’s logs on the second run, followed by successful installation and tests.

Choose what to cache with pnpm

pnpm keeps downloaded package files in a store, then creates the installed dependencies your project uses. These caches serve different purposes: Start with the store. Compare installed dependencies if installation remains a large part of your job. See restore performance when a large number of small files makes extraction slow.

Save the pnpm store

Commit pnpm-lock.yaml and set an exact pnpm version in the packageManager field of your root package.json. For a project with a pnpm test command, save this workflow as .github/workflows/pnpm-tests.yml:
.github/workflows/pnpm-tests.yml
Install pnpm before setup-node so the setup action can find the store. Its cache: pnpm option saves the store; it recreates installed dependencies during the install step. --frozen-lockfile requires the committed lockfile to agree with your package definitions. Run the workflow twice with the same lockfile. On the second run, check the setup action’s logs for a restored store and confirm that installation and tests succeed.

Save installed dependencies and verification results

For a pnpm monorepo (several packages in one repository), include the root and every package’s node_modules. A cache key names a saved entry. Include the operating system, processor architecture, Node.js and pnpm versions, lockfile, package definitions, local package changes, and installation settings in that key. These details help you restore files built for the same environment. pnpm v11 introduced lockfile policy verification: checks that locked package versions meet your dependency rules. Versions that use lockfile-verified.jsonl save a successful check in the configured cache directory. Keeping that record lets pnpm reuse an accepted result for the same lockfile and compatible rules. The record is separate from the store and installed dependencies. Its availability depends on your pnpm version and installation settings. See pnpm’s verification design. In the pnpm workflow above, replace the setup-node and install steps with these steps. Keep checkout, pnpm setup, and the final test step:
Use this as an alternative to cache: pnpm. Adjust apps/*/node_modules and packages/*/node_modules to match the package locations in pnpm-workspace.yaml. Add any custom patch paths or installation settings to hashFiles, which includes those files’ contents in the key. Keep the install step on every run so pnpm checks the restored dependencies and handles a miss. Use an exact key for installed dependencies. This example leaves restore-keys unset so it restores only an exact match. The example sets --cache-dir explicitly so the saved path matches the install path. Keep your dependency policy checks enabled and let pnpm decide whether a saved verification result is valid.

Reuse Turborepo task results

Celesto saves Turborepo task results automatically, with no extra setup. See Turbo cache.

Reuse Nx task results

Nx also reuses completed tasks, but its local cache checks which machine created the files. Each Celesto job gets a fresh computer. Copying Nx’s local cache through actions/cache can produce an unknown local cache error. Use Nx Cloud or a supported self-hosted remote cache for task results shared between jobs. Continue caching npm or pnpm dependencies through Celesto. Set up the remote cache’s read and write permissions for your default branch and pull requests using that provider’s instructions. Keep Nx’s checks for trusted cache files enabled. Follow the chosen provider’s Nx setup instructions to share task results between computers.

Cache Docker builds separately

Docker saves reusable parts of an image, called layers, separately from your dependency and task caches. Save and restore them with cache-to and cache-from set to type=gha, as shown in Cache image layers between jobs.
Last modified on November 4, 2026