Skip to content
Latchkey

CI/CD for React with GitHub Actions

Lint, test, and build your React app on every push, then publish the static bundle.

A React single-page app compiles to static HTML, CSS, and JavaScript, which makes its pipeline simple: check quality, build a bundle, and upload it. This recipe covers both Create React App and Vite projects with one workflow you can adapt by changing the build command.

What the pipeline does

  • install deps with npm ci
  • lint with eslint
  • run tests in CI mode
  • build the static bundle
  • upload or deploy the output

The workflow

This builds a React app and deploys the output to GitHub Pages. For CRA the build output is build/; for Vite it is dist/ (adjust the path).

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run lint --if-present
      - run: npm test -- --watchAll=false
        env:
          CI: true
      - run: npm run build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: build
  deploy:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment:
      name: github-pages
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

Caching and speed

cache: npm restores the npm download cache so installs are quick. Jest and Vitest both honor CI=true to run once and exit. The build is the slowest step for large component trees; running it on faster, cheaper managed runners like Latchkey trims wall-clock time on every PR.

Deploying

GitHub Pages (shown above) is free and ideal for project sites. For production traffic, upload the bundle to S3 behind CloudFront, or connect the repo to Netlify, Vercel, or Cloudflare Pages for automatic deploys and preview URLs on pull requests.

Key takeaways

  • A React SPA pipeline is just check, build, upload.
  • Set CI=true so test runners exit instead of watching.
  • GitHub Pages is the simplest host; S3+CloudFront scales for production.

Related guides

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