1node.si
← Registry

gh-actions-nodejs-build

cleared

Builds Node.js frontends or packages in GitHub Actions using actions/setup-node, npm or yarn installs, and working-directory for monorepo apps. Defaults Node to latest LTS unless package.json engines or the user pins a version. Use when authoring Node CI, frontend builds, or combining multiple JS packages in one job.

files.jsonSKILL.md
---
name: gh-actions-nodejs-build
description: >-
  Builds Node.js frontends or packages in GitHub Actions using actions/setup-node,
  npm or yarn installs, and working-directory for monorepo apps. Defaults Node to
  latest LTS unless package.json engines or the user pins a version. Use when
  authoring Node CI, frontend builds, or combining multiple JS packages in one job.
---

# GitHub Actions: Node.js build

Official action: [actions/setup-node](https://github.com/actions/setup-node).

## Node version (priority)

1. **User-requested** version (conversation or workflow variable)—use that.
2. **`package.json`** **`engines.node`** when it is a **strict** requirement—honor the range or exact version.
3. **Default:** **`node-version: 'lts/*'`** so CI tracks current Node LTS without manual bumps.

Optionally set **`node-version-file: package.json`** (or **`.nvmrc`**) when the repo already pins the version there—still prefer **`lts/*`** if there is no **`engines`** constraint and no pin file.

Re-check **`uses:`** for **`actions/setup-node`** with **`update-github-actions-versions`**.

## Minimal pattern

On **`ubuntu-latest`** (or Linux-compatible self-hosted runners):

1. **`actions/checkout`**
2. **`actions/setup-node`** with **`node-version`** (or **`node-version-file`**) and optional **`cache`** (see [reference.md](reference.md)).
3. **Install** — **`npm ci`** when **`package-lock.json`** exists; otherwise **`npm install`**. Use **`yarn install --frozen-lockfile`** when **`yarn.lock`** exists.
4. **Build** — **`npm run <script>`** or **`yarn run <script>`** matching **`package.json`** **`scripts`** (often **`build`**).

Use **`working-directory:`** on steps (or **`defaults.run.working-directory`**) for each app in a monorepo.

## Multiple packages in one job

Repeat **Install + Build** with different **`working-directory`** values (e.g. one package on **npm**, another on **yarn**)—see [reference.md](reference.md).

## Step identifiers

Set **`id:`** on **setup-node**, **install**, and **build** steps per **`ci-cd-pipeline-foundation`**.

## Outputs and artifacts

If deploy needs a **dist** folder, **`actions/upload-artifact`** or pass the path to a later step (static hosting, Docker, Azure, etc.).

**Azure Static Web Apps:** keep **`staticwebapp.config.json`** at the app root and copy it into **`dist`** after build so **`navigationFallback`** applies—otherwise SPA deep links fail. See [Azure Static Web Apps configuration](https://learn.microsoft.com/azure/static-web-apps/configuration#example-configuration-file). For Azure DevOps SWA deploy, see **`ado-azure-static-web-apps`**.

## Vite / heavy frontends

- Cache **`node_modules/.vite`** (or your bundler cache) with **`actions/cache`**, keyed by lockfile + config—see [reference.md](reference.md).
- Pass **`VITE_*`** (or **`NODE_ENV`**) through **`env:`** on the build step; use **`${{ vars.* }}`** for non-secrets.

## Job-level Node pin

Teams may set **`env.NODE_VERSION`** and pass **`${{ env.NODE_VERSION }}`** to **`setup-node`**—honor that over **`lts/*`** when intentional.

## YAML examples

See [reference.md](reference.md).