Skip to content
Latchkey

How to Install serialport in CI

serialport relies on a native bindings addon (@serialport/bindings-cpp). CI fails when the prebuilt binding does not match the runner Node ABI or platform.

The native part of serialport ships prebuilt bindings via prebuild for common Node versions and platforms. A mismatch or a missing prebuilt forces a node-gyp source build.

Why it fails in CI

  • The runner Node ABI differs from the prebuilt binding → NODE_MODULE_VERSION mismatch.
  • Alpine/musl or an uncommon arch has no prebuilt → source build needs python3 + g++ + make.
  • A node_modules cached under a different Node version carries an incompatible binding.

Install it reliably

Install fresh on the pinned Node version. Provide the toolchain for source builds and rebuild after a Node change.

Terminal
# common platforms: prebuilt binding
npm ci

# Alpine / source build
apk add --no-cache python3 make g++ linux-headers
npm install serialport --build-from-source

# after a Node version change
npm rebuild @serialport/bindings-cpp

Cache & speed

Cache ~/.npm keyed on lockfile + Node version. If you cache node_modules, include the Node version in the key so an ABI change invalidates the native binding.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: npm-${{ runner.os }}-node${{ matrix.node }}-${{ hashFiles('**/package-lock.json') }}

Common errors

  • The module ... was compiled against a different Node.js versionnpm rebuild @serialport/bindings-cpp.
  • prebuild-install warn install No prebuilt binaries found → install python3 + g++.
  • fatal error: linux/serial.h on Alpine → install linux-headers.

Key takeaways

  • serialport's native bindings must match the runner Node ABI, or rebuild from source.
  • Run npm rebuild @serialport/bindings-cpp after changing Node versions.
  • Alpine needs linux-headers plus the C/C++ toolchain.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →