Skip to content

Node.js

Node.js CI on GitHub Actions

npm ci writes tens of thousands of small files on every run.

95s → 11s
npm ci
6m → 2m
Full pipeline
6 GB/s
Disk throughput

npm ci writes tens of thousands of small files on every run.

Why it happens

node_modules is a filesystem stress test, and network-attached CI storage is the worst possible place to run one.

What to change

  1. Cache ~/.npm and restore node_modules directly rather than reinstalling
  2. Move to pnpm — its content-addressed store makes installs near-instant on a warm cache
  3. Run on a runner with local NVMe; this workload is disk-bound, not CPU-bound
  4. Use --prefer-offline so a warm cache is not revalidated over the network

Node.js on runnerhut

yaml
jobs:
test:
runs-on: runnerhut-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- run: npm ci --prefer-offline
- run: npm test
A working starting point

The only runnerhut-specific line is `runs-on: runnerhut-4vcpu-ubuntu-2404`. Everything else is standard GitHub Actions — the same actions, the same secrets and the same permissions model you use today.

Your next build could be twice as fast, at half the price

Start free. Migrating away is the same one line, and we publish that diff too.