CI/CD for a Component Library with GitHub Actions
Validate, build, and publish your design-system package automatically.
A reusable component or Tailwind library ships as an npm package rather than a deployed site, so the pipeline ends in a publish rather than an upload. This recipe lints and tests on every PR, then builds and publishes to npm when you push a version tag.
What the pipeline does
- install deps with npm ci
- lint and typecheck
- test with vitest
- build ESM and CJS bundles with tsup
- publish to npm on a version tag
The workflow
The publish job only runs on tags like v1.2.3. Set registry-url so setup-node configures auth, and provide NODE_AUTH_TOKEN from an npm automation token.
name: CI
on:
push:
branches: [main]
tags: ['v*']
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
registry-url: https://registry.npmjs.org
- run: npm ci
- run: npm run lint --if-present
- run: npx tsc --noEmit
- run: npx vitest run
- run: npm run build
publish:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
registry-url: https://registry.npmjs.org
- run: npm ci
- run: npm run build
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}Caching and speed
cache: npm covers installs. If you ship compiled CSS, make sure Tailwind purges unused classes via your content config so the published bundle stays small. tsup is fast, so the publish job is dominated by install; cheaper managed runners such as Latchkey keep release builds quick and inexpensive.
Deploying
Publishing means pushing the built package to a registry, not deploying a site. The workflow publishes to npm on a version tag; for a private registry, swap registry-url and the token. Pair this with Changesets to automate version bumps and changelog entries on merge.
Key takeaways
- A library publishes to a registry instead of deploying a site.
- Gate the publish job on a version tag (refs/tags/v*).
- Set registry-url and NODE_AUTH_TOKEN so npm publish authenticates.