CI/CD for Vite with GitHub Actions
A framework-agnostic Vite pipeline you can reuse for any front-end stack.
Vite powers React, Vue, Svelte, Solid, and vanilla projects, so a single pipeline shape works across them. This recipe lints, type-checks, runs Vitest, builds the dist bundle, and deploys it to a static host.
What the pipeline does
- install deps with npm ci
- lint with eslint
- type-check with tsc
- test with vitest run
- build with vite build
- deploy the dist output
The workflow
vitest run executes once and exits, which is what you want in CI. Vite always builds to dist/ unless you override build.outDir.
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: npx tsc --noEmit --if-present || true
- run: npx vitest run
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment:
name: github-pages
steps:
- uses: actions/deploy-pages@v4Caching and speed
cache: npm restores installs and Vite stores a dependency pre-bundle in node_modules/.vite that actions/cache can persist. Vite builds are quick already, so the limiting factor is usually install plus test time; cheaper managed runners like Latchkey (about 69% cheaper than GitHub-hosted) keep frequent CI runs affordable.
Deploying
Set base in vite.config when serving from a subpath like GitHub Pages. dist/ deploys to Pages, Netlify, Cloudflare Pages, or S3+CloudFront. Because the output is plain static assets, any CDN or object store works.
Key takeaways
- Use vitest run (not watch) and tsc --noEmit in CI.
- Set Vite base to match a subpath deploy.
- dist/ is portable to any static host or CDN.