Fullstack Developer & Whitewater Kayaker & Scout
Discover how to optimize dependency installation on GitHub Actions for modern package managers like Yarn. Learn about custom caching actions and the latest features of actions/setup-node to speed up your CI/CD pipeline significantly.
Since migrating a few of my projects to Yarn Modern, I have been struggling with speeding up the dependency installation process on GitHub Actions.
From the beginning, I have been using the great bahmutov/npm-install
action
that handles the caching of node_modules
for Yarn v1.22.22 very well.
With the configuration looking like this...
- name: Install dependencies
uses: bahmutov/npm-install@v1.10.2
with:
useRollingCache: true
install-command: yarn --immutable
...the caching was working great and the CI runs were fast.
However as I started to migrate the project to Yarn v3 and v4, I noticed that the cache was consistently missed.
There is still an open GitHub issue bahmutov/npm-install#28 that is tracking this problem.
I have started investigating how to achieve better performance for Yarn Modern while installing dependencies on GitHub Actions. I have discovered a few viable solutions worth sharing.
In a Discord repository, I have found a custom caching action that is handling the caching using actions/cache
.
The solution is simple:
You can check their implementation in the Discord repository.
This is a good and usable solution if you want to take care of the caching yourself. But I did not want to deal with this.
I am also using the actions/setup-node
for configuring the Node.js environment for me.
And in one of their most recent release
I discovered that they have added a new feature for caching the package manager's cache.
Caching dependencies
The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are npm, yarn. The cache input is optional, and caching is turned off by default.
- name: Enable Corepack
run: corepack enable # Set up a package manager for us
- name: Configure Node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc' # Use node version file
cache: 'yarn' # 'npm' or 'yarn'
cache-dependency-path: yarn.lock # path to a dependency file
- name: Install dependencies
run: yarn --immutable --inline-builds
Since using this configuration, I have been able to speed up my dependency installation process on GitHub Actions twice.
But this approach caches only the package managers global cache like ~/.npm
or ~/.yarn/cache
.
Additionally using actions/cache
another layer of the caching can be added.
So state of the node_modules
can be cached and restored to speed up the pipeline even more.
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
This approach leads to another few spared seconds in your pipelines.