How to Run esbuild in CI Across Platforms
esbuild is a native Go binary delivered through per-platform optional dependencies. CI breaks when the installed binary does not match the runner.
esbuild installs a platform-specific package (e.g. @esbuild/linux-x64) as an optional dependency. A lockfile built on another OS, or --no-optional, leaves the wrong binary or none at all.
Why it fails in CI
- The lockfile was generated on macOS/Windows, so the Linux binary is absent → host mismatch error.
npm ci --omit=optionaldropped the platform package.- A
node_modulescached from another OS carries the wrong esbuild binary.
Install and run it reliably
Install fresh on the runner with optional dependencies enabled so the correct platform package resolves. Do not copy node_modules across operating systems.
Terminal
# clean install on the target platform, optional deps ON
npm ci
# verify the platform binary resolved
node -e "console.log(require('esbuild').version)"Cache & speed
esbuild is tiny and fast; standard ~/.npm caching is plenty. Avoid caching node_modules across OS/arch since the binary is platform-specific.
.github/workflows/ci.yml
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}Common errors
Host version "x" does not match binary version "y"→ reinstall on the runner; mismatched packages.Cannot find module @esbuild/linux-x64→ optional deps were omitted; reinstall with them enabled.spawn .../esbuild EACCES→ the binary lost its executable bit (bad cache restore); reinstall.
Key takeaways
- esbuild ships a per-platform optional dependency - keep optional deps enabled.
- Install fresh on the runner; never reuse node_modules across OS/arch.
- Generate the lockfile on Linux if your CI runs on Linux.
Related guides
How to Run SWC (@swc/core) in CIRun @swc/core in CI: install the right native binding via optional dependencies, handle musl/glibc, cache cor…
How to Install sharp in CI Without Build FailuresInstall sharp reliably in CI: use the prebuilt libvips binaries, avoid musl/Alpine mismatches, and stop "Coul…
How to Make node-gyp Builds Work in CIFix node-gyp build failures in CI: install Python and a C/C++ toolchain, and stop "gyp ERR! find Python" and…
Self-Healing CI: Missing System Packages and Setup GapsA missing system library or tool fails the build until someone installs it. See the manual fix and how self-h…