Speed Up Your Vite Builds with Caching in GitHub Actions

@fakhrulnugrohoAugust 28, 2024

If your CI spends most of its time on yarn install for packages that haven't changed, caching is the cheapest speedup available. GitHub Actions ships a first-class cache action — the only real work is deciding what to cache and how to key it.

Here's the setup I use for a Vite + Yarn project.

⚙️ The workflow

The workflow file lives in .github/workflows/:

YAML
name: Build and Cache Vite

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "18" # Specify your Node.js version

      - name: Cache Yarn modules
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/yarn
            ~/.yarn/cache
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Install dependencies
        run: yarn install

      - name: Cache Vite build output
        uses: actions/cache@v3
        with:
          path: |
            dist
          key: ${{ runner.os }}-vite-${{ hashFiles('**/vite.config.js') }}
          restore-keys: |
            ${{ runner.os }}-vite-

      - name: Build project
        run: yarn build

      - name: Deploy or run tests
        run: echo "Deploy or run tests here"

🔍 What each step does

🔑 How the cache keys actually behave

Two details worth understanding instead of copy-pasting:

One honest caveat: caching dist keyed on the Vite config only pays off when the build can genuinely reuse previous output — Vite still rebuilds sources that changed. In most projects, the Yarn cache is where nearly all the savings come from, so measure before assuming the build-output cache helps.

🔚 Conclusion

With both caches in place, a build with unchanged dependencies skips the download step almost entirely — on a typical project that's minutes saved on every push and pull request, for about twenty lines of YAML.

Happy coding 🚀