GitHub Actions workflow for Node.js (lint, tests and build)
A continuous integration workflow for a Node.js project: it installs with npm ci and runs lint, tests and build on several Node versions, with npm caching. This is the exact YAML the application generates.
When to use it
- Your project has a package.json and a package-lock.json.
- You want to run lint, tests and build on several Node versions.
- You want a safe starting point to build on (deployment, publishing…).
The complete workflow
name: Node CI
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: Node ${{ matrix.node-version }}
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
node-version:
- 20
- 22
- 24
fail-fast: false
steps:
- name: Check out the code (actions/checkout v7.0.1)
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Node (actions/setup-node v7.1.0)
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint --if-present
- name: Tests
run: npm test --if-present
- name: Build
run: npm run build --if-present
It is a starting point: you can open it in the editor, change events, jobs and steps, and the application validates it again before generating the file.
Before you use it
- Needs a package-lock.json (it uses `npm ci`).
- The `lint`, `test` and `build` scripts only run if they exist in your package.json (`--if-present`).
- Change the matrix versions to the ones your project supports.
What each part does
- EventsThe workflow runs on pushes to main, on pull requests targeting main, and manually from the Actions tab (workflow_dispatch).
- Version matrixA matrix with three Node versions creates one job per version; with fail-fast disabled, a failure in one does not cancel the others.
- Optional scriptsThe lint, test and build scripts only run if they exist in your package.json (--if-present), so the template does not fail for lacking them.
- npm cacheThe action that installs Node stores the npm cache between runs.
- Permissions and securityMinimal permissions: the token can only read the repository contents (contents: read). Third-party actions are pinned to a specific commit SHA (with the readable version in the step name), not to a movable tag.
- Maximum timeEvery job has a maximum run time (timeout-minutes) so a hang cannot burn minutes forever.
How to use it in your repository
- Save the file in the .github/workflows/ folder of your repository.
- Push it (commit and push). GitHub detects the workflow and runs it according to its events.
- Check the result in the Actions tab of the repository.
Frequently asked questions
Why npm ci and not npm install?
npm ci installs exactly what package-lock.json says and fails if it does not match package.json, which makes runs reproducible.
What if I use pnpm or yarn?
Change the install-dependencies step and the Node action cache to your manager's. The rest of the template works the same.
How do I change the Node versions?
Edit the matrix list (node-version) to the versions your project supports.
Other templates
- GitHub Actions workflow for Python (pytest)Installs dependencies and runs pytest on several Python versions with pip caching.
- GitHub Actions workflow to build and publish a Docker image to GHCRBuilds the repository image and publishes it to GitHub Container Registry (ghcr.io) when you push to main or create a v* tag.
Try it for free
The editor is available with a free account, with usage limits. Nothing runs in your repository or your installation: you decide which file to use.