Building and testing Node.js
Learn how to create a continuous integration (CI) workflow to build and test your Node.js project.
In this article
Introduction
This guide shows you how to create a continuous integration (CI) workflow that builds and tests Node.js code. If your CI tests pass, you may want to deploy your code or publish a package.
Prerequisites
We recommend that you have a basic understanding of Node.js, YAML, workflow configuration options, and how to create a workflow file. For more information, see:
Using a Node.js workflow template
To get started quickly, add a workflow template to the.github/workflows
directory of your repository.
GitHub provides a workflow template for Node.js that should work for most Node.js projects. The subsequent sections of this guide give examples of how you can customize this workflow template.
On GitHub, navigate to the main page of the repository.
Under your repository name, click Actions.
If you already have a workflow in your repository, clickNew workflow.
The "Choose a workflow" page shows a selection of recommended workflow templates. Search for "Node.js".
Filter the selection of workflows by clickingContinuous integration.
On the "Node.js" workflow, clickConfigure.
Edit the workflow as required. For example, change the Node versions you want to use.
ClickCommit changes.
The
node.js.yml
workflow file is added to the.github/workflows
directory of your repository.
Specifying the Node.js version
The easiest way to specify a Node.js version is by using thesetup-node
action provided by GitHub. For more information see,setup-node
.
Thesetup-node
action takes a Node.js version as an input and configures that version on the runner. Thesetup-node
action finds a specific version of Node.js from the tools cache on each runner and adds the necessary binaries toPATH
, which persists for the rest of the job. Using thesetup-node
action is the recommended way of using Node.js with GitHub Actions because it ensures consistent behavior across different runners and different versions of Node.js. If you are using a self-hosted runner, you must install Node.js and add it toPATH
.
The workflow template includes a matrix strategy that builds and tests your code with the Node.js versions listed innode-version
. The 'x' in the version number is a wildcard character that matches the latest minor and patch release available for a version. Each version of Node.js specified in thenode-version
array creates a job that runs the same steps.
Each job can access the value defined in the matrixnode-version
array using thematrix
context. Thesetup-node
action uses the context as thenode-version
input. Thesetup-node
action configures each job with a different Node.js version before building and testing code. For more information about matrix strategies and contexts, seeWorkflow syntax for GitHub Actions andContexts reference.
strategy: matrix: node-version: ['18.x', '20.x']steps:- uses: actions/checkout@v5- name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }}
strategy:matrix:node-version: ['18.x','20.x']steps:-uses:actions/checkout@v5-name:UseNode.js${{matrix.node-version}}uses:actions/setup-node@v4with:node-version:${{matrix.node-version}}
Alternatively, you can build and test with exact Node.js versions.
strategy: matrix: node-version: ['10.17.0', '17.9.0']
strategy:matrix:node-version: ['10.17.0','17.9.0']
Or, you can build and test using a single version of Node.js too.
name: Node.js CIon: [push]jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x' - run: npm ci - run: npm run build --if-present - run: npm test
name:Node.jsCIon: [push]jobs:build:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-run:npmci-run:npmrunbuild--if-present-run:npmtest
If you don't specify a Node.js version, GitHub uses the environment's default Node.js version.For more information, seeGitHub-hosted runners.
Installing dependencies
GitHub-hosted runners have npm and Yarn dependency managers installed. You can use npm and Yarn to install dependencies in your workflow before building and testing your code. The Windows and Linux GitHub-hosted runners also have Grunt, Gulp, and Bower installed.
You can also cache dependencies to speed up your workflow. For more information, seeDependency caching reference.
Example using npm
This example installs the versions in thepackage-lock.json
ornpm-shrinkwrap.json
file and prevents updates to the lock file. Usingnpm ci
is generally faster than runningnpm install
. For more information, seenpm ci
andIntroducingnpm ci
for faster, more reliable builds.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x'- name: Install dependencies run: npm ci
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-name:Installdependenciesrun:npmci
Usingnpm install
installs the dependencies defined in thepackage.json
file. For more information, seenpm install
.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x'- name: Install dependencies run: npm install
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-name:Installdependenciesrun:npminstall
Example using Yarn
This example installs the dependencies defined in theyarn.lock
file and prevents updates to theyarn.lock
file. For more information, seeyarn install
.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x'- name: Install dependencies run: yarn --frozen-lockfile
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-name:Installdependenciesrun:yarn--frozen-lockfile
Alternatively, you can install the dependencies defined in thepackage.json
file.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x'- name: Install dependencies run: yarn
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-name:Installdependenciesrun:yarn
Example using a private registry and creating the .npmrc file
You can use thesetup-node
action to create a local.npmrc
file on the runner that configures the default registry and scope. Thesetup-node
action also accepts an authentication token as input, used to access private registries or publish node packages. For more information, seesetup-node
.
To authenticate to your private registry, you'll need to store your npm authentication token as a secret. For example, create a repository secret calledNPM_TOKEN
. For more information, seeUsing secrets in GitHub Actions.
In the example below, the secretNPM_TOKEN
stores the npm authentication token. Thesetup-node
action configures the.npmrc
file to read the npm authentication token from theNODE_AUTH_TOKEN
environment variable. When using thesetup-node
action to create an.npmrc
file, you must set theNODE_AUTH_TOKEN
environment variable with the secret that contains your npm authentication token.
Before installing dependencies, use thesetup-node
action to create the.npmrc
file. The action has two input parameters. Thenode-version
parameter sets the Node.js version, and theregistry-url
parameter sets the default registry. If your package registry uses scopes, you must use thescope
parameter. For more information, seenpm-scope
.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: always-auth: true node-version: '20.x' registry-url: https://registry.npmjs.org scope: '@octocat'- name: Install dependencies run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:always-auth:truenode-version:'20.x'registry-url:https://registry.npmjs.orgscope:'@octocat'-name:Installdependenciesrun:npmcienv:NODE_AUTH_TOKEN:${{secrets.NPM_TOKEN}}
The example above creates an.npmrc
file with the following contents:
//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}@octocat:registry=https://registry.npmjs.org/always-auth=true
Example caching dependencies
You can cache and restore the dependencies using thesetup-node
action.
The following example caches dependencies for npm.
steps:- uses: actions/checkout@v5- uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'- run: npm install- run: npm test
steps:-uses:actions/checkout@v5-uses:actions/setup-node@v4with:node-version:'20'cache:'npm'-run:npminstall-run:npmtest
The following example caches dependencies for Yarn.
steps:- uses: actions/checkout@v5- uses: actions/setup-node@v4 with: node-version: '20' cache: 'yarn'- run: yarn- run: yarn test
steps:-uses:actions/checkout@v5-uses:actions/setup-node@v4with:node-version:'20'cache:'yarn'-run:yarn-run:yarntest
The following example caches dependencies for pnpm (v6.10+).
# This workflow uses actions that are not certified by GitHub.# They are provided by a third-party and are governed by# separate terms of service, privacy policy, and support# documentation.# NOTE: pnpm caching support requires pnpm version >= 6.10.0steps:- uses: actions/checkout@v5- uses: pnpm/action-setup@0609f0983b7a228f052f81ef4c3d6510cae254ad with: version: 6.10.0- uses: actions/setup-node@v4 with: node-version: '20' cache: 'pnpm'- run: pnpm install- run: pnpm test
# This workflow uses actions that are not certified by GitHub.# They are provided by a third-party and are governed by# separate terms of service, privacy policy, and support# documentation.#NOTE: pnpm caching support requires pnpm version >= 6.10.0steps:-uses:actions/checkout@v5-uses:pnpm/action-setup@0609f0983b7a228f052f81ef4c3d6510cae254adwith:version:6.10.0-uses:actions/setup-node@v4with:node-version:'20'cache:'pnpm'-run:pnpminstall-run:pnpmtest
If you have a custom requirement or need finer controls for caching, you can use thecache
action. For more information, seeDependency caching reference.
Building and testing your code
You can use the same commands that you use locally to build and test your code. For example, if you runnpm run build
to run build steps defined in yourpackage.json
file andnpm test
to run your test suite, you would add those commands in your workflow file.
steps:- uses: actions/checkout@v5- name: Use Node.js uses: actions/setup-node@v4 with: node-version: '20.x'- run: npm install- run: npm run build --if-present- run: npm test
steps:-uses:actions/checkout@v5-name:UseNode.jsuses:actions/setup-node@v4with:node-version:'20.x'-run:npminstall-run:npmrunbuild--if-present-run:npmtest
Packaging workflow data as artifacts
You can save artifacts from your build and test steps to view after a job completes. For example, you may need to save log files, core dumps, test results, or screenshots. For more information, seeStore and share data with workflow artifacts.
Publishing to package registries
You can configure your workflow to publish your Node.js package to a package registry after your CI tests pass. For more information about publishing to npm and GitHub Packages, seePublishing Node.js packages.