How to Install cpu-features in CI Without Build Failures
cpu-features is a small native addon pulled in as an optional dependency by packages like grpc and ssh2 - it compiles via node-gyp and breaks slim CI images.
cpu-features is a C++ addon that detects CPU capabilities at runtime. It is usually an optional dependency of @grpc/grpc-js’s native sibling, ssh2, and similar packages. On a slim image it tries to compile via node-gyp and fails, even though its callers work without it.
Why it fails in CI
- cpu-features triggers a node-gyp build needing python3 + g++; slim/Alpine images lack both.
- Alpine/musl has no prebuilt, forcing a source build.
- A node_modules cached under another Node ABI carries an incompatible
.node.
Install it reliably
Either provide the toolchain so the optional addon compiles, or omit it - packages that pull in cpu-features (ssh2, grpc) detect its absence and fall back to a pure-JS path.
# Option A: build it (Debian/Ubuntu)
apt-get update && apt-get install -y python3 make g++ build-essential
npm ci
# Option B: skip the optional native speedup
npm ci --omit=optional
# ssh2 / grpc work without cpu-features (reduced CPU-feature detection)Cache & speed
Cache ~/.npm keyed on lockfile + Node version. If you build the addon, also cache ~/.cache/node-gyp. Omitting it skips the compile entirely.
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-node${{ matrix.node }}-${{ hashFiles('**/package-lock.json') }}Common errors
gyp ERR!building cpu-features → install python3 + g++, or--omit=optional.gyp ERR! find Python→ install python3.NODE_MODULE_VERSIONmismatch →npm rebuild cpu-featureson the target Node.
Key takeaways
- cpu-features is an optional native addon pulled in by ssh2/grpc.
- Install python3 + g++ to build it, or
--omit=optionalto skip it. - Callers degrade gracefully without it; omitting it is safe.