Introduction

Node.js native addons compiled with N-API (Node API) are binary modules that must be compiled against the specific Node.js ABI version. When a native addon was compiled for Node.js 16 but the application runs on Node.js 18, the addon fails to load with Error: The module was compiled against a different Node.js version or NODE_MODULE_VERSION mismatch. This error commonly occurs after Node.js upgrades, when deploying pre-built binaries across environments, or when node_modules is copied between machines with different Node.js versions.

Symptoms

``` node:internal/modules/cjs/loader:1210 return process.dlopen(module, filename); ^

Error: The module '/app/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 93. This version of Node.js requires NODE_MODULE_VERSION 108. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install). at Object.Module._extensions..node (node:internal/modules/cjs/loader:1210:18) ```

Or:

bash
Error: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.32' not found
(required by /app/node_modules/sharp/build/Release/sharp-linux-x64.node)

Common Causes

  • Node.js version changed: Upgraded Node.js without rebuilding native addons
  • Copied node_modules between machines: Pre-built binaries are platform-specific
  • Docker build with different base image: Build stage uses Node.js 18, runtime uses Node.js 16
  • Native addon not published for your platform: No pre-built binary available for your OS/arch
  • Missing build tools: node-gyp cannot rebuild because Python or build-essential is missing
  • ABI version mismatch in CI: CI environment has different Node.js version than local development

Step-by-Step Fix

Step 1: Rebuild native addons

```bash # Rebuild all native addons in the project npm rebuild

# Or reinstall the specific package npm install bcrypt --build-from-source

# For all native addons npm install --build-from-source ```

Step 2: Ensure build tools are available

```bash # Ubuntu/Debian sudo apt-get install -y python3 make g++

# For node-gyp specifically npm install -g node-gyp

# Verify build environment node-gyp --python /usr/bin/python3 find-python ```

Step 3: Use prebuild-install for automatic binary downloads

In your package.json:

json
{
    "scripts": {
        "install": "prebuild-install || node-gyp rebuild",
        "rebuild": "node-gyp rebuild"
    },
    "binary": {
        "napi_versions": [3, 4, 5, 6]
    }
}

Step 4: Fix Docker multi-stage builds

```dockerfile # Build stage FROM node:18-slim AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build

# Runtime stage - must use same Node.js major version FROM node:18-slim WORKDIR /app

# Install build dependencies for native addon compilation RUN apt-get update && apt-get install -y --no-install-recommends \ python3 make g++ \ && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist

# Rebuild native addons for the runtime environment RUN npm rebuild

CMD ["node", "dist/server.js"] ```

Prevention

  • Always run npm rebuild after changing Node.js versions
  • Pin the Node.js version in your Dockerfile and CI configuration
  • Use engines in package.json to specify required Node.js version
  • Commit package-lock.json and use npm ci for reproducible builds
  • Test native addon compatibility when upgrading Node.js
  • Use napi_version in your native addon's binding.gyp to target multiple N-API versions
  • Consider using pure-JS alternatives to native addons when available