Fix 'Error: Cannot find module ../build/Release/addon.node' After Upgrading Node.js

intermediate๐Ÿ’š Node.js2026-05-06| Node.js (any version upgrade), npm/yarn/pnpm, Linux/macOS/Windows, packages: bcrypt, sharp, canvas, sqlite3, node-sass, argon2

Error Message

Error: Cannot find module '../build/Release/addon.node' Require stack: - /app/node_modules/bcrypt/lib/bcrypt.js
#nodejs#native-addon#node-gyp#rebuild#bcrypt#sharp

The scenario

You upgraded Node.js from v18 to v20. Ran the app. Got this:

Error: Cannot find module '../build/Release/addon.node'
Require stack:
- /app/node_modules/bcrypt/lib/bcrypt.js

node_modules is still there. You didn't touch a single config file. Nothing changed except the Node.js version. Yet the app refuses to start.

Why this happens

Packages like bcrypt, sharp, canvas, sqlite3, and node-sass aren't pure JavaScript. They contain C/C++ code that gets compiled into a .node binary โ€” and that binary is tied to a specific Node.js ABI (Application Binary Interface) version.

Node.js v18 uses ABI 108. Node.js v20 uses ABI 115. The old binary speaks a different dialect. Node can't load it, so you see the "missing module" error even though the file physically exists on disk.

That's also why npm install alone doesn't fix it. npm sees the package as installed and skips recompilation entirely.

Quick fix โ€” rebuild native addons

Three options, in order of how often they work:

Option 1: npm rebuild (try this first)

# Run from your project root
npm rebuild

This recompiles every native addon against your current Node.js version. Takes 30โ€“60 seconds on a typical project. Usually that's all you need.

Option 2: Nuke node_modules and reinstall

If npm rebuild throws errors or leaves things half-broken, do a clean reinstall:

# npm
rm -rf node_modules
npm install

# yarn
rm -rf node_modules
yarn install

# pnpm
rm -rf node_modules
pnpm install

Slower, but more thorough. This forces a fresh compile of everything from scratch.

Option 3: Rebuild one specific package

Only one addon is broken? Don't nuke everything. Target it directly:

npm rebuild bcrypt

If rebuild still fails โ€” you're missing build tools

The compile step runs through node-gyp, which needs a C++ compiler and Python 3 on your machine. Without them, you'll hit errors like gyp ERR! stack Error: not found: make or python: command not found.

Ubuntu/Debian

sudo apt-get install -y build-essential python3

RHEL/CentOS/Amazon Linux

sudo yum groupinstall 'Development Tools'
sudo yum install python3

macOS

xcode-select --install

This installs Apple's command-line developer tools, which includes clang and make. The download is around 200 MB.

Windows

The old windows-build-tools npm package is deprecated and broken on modern Node.js. Go straight to the source instead:

  • Download Visual Studio Build Tools 2022 from Microsoft's website
  • During install, select the "Desktop development with C++" workload
  • Make sure Python 3 is also installed (the installer can optionally include it)

After that, retry npm rebuild in a fresh terminal window.

Docker and CI environments

Docker is a common trap here. You update your base image from node:18-alpine to node:20-alpine, but Docker reuses a cached layer that still has the old compiled binaries. The app breaks at runtime, and the image build looked fine.

The fix is a clean install in the Dockerfile, with build tools available:

FROM node:20-alpine
RUN apk add --no-cache python3 make g++
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

Using Docker Compose with a named volume for node_modules? The old binaries live in that volume even after rebuilding the image. Remove it:

docker-compose down -v
docker-compose up --build

Verify the fix worked

Check that the .node binary was actually recompiled โ€” the timestamp should be recent:

# bcrypt
ls -la node_modules/bcrypt/lib/binding/

# sharp
ls -la node_modules/sharp/build/Release/

Then do a quick smoke test before starting the full app:

node -e "require('bcrypt'); console.log('bcrypt OK')"
node -e "require('sharp'); console.log('sharp OK')"

If those print OK, you're done.

Prevent this from happening again

The underlying problem is version mismatch. Lock it down with a .nvmrc file in your project root:

# .nvmrc
20.11.0

Now everyone on the team โ€” and every CI run โ€” uses the same version:

nvm use  # reads .nvmrc automatically

GitHub Actions:

- uses: actions/setup-node@v4
  with:
    node-version-file: '.nvmrc'

One file, no more "works on my machine" version drift.

Tips

When chasing native addon weirdness, it's sometimes useful to confirm whether a .node binary actually changed after a rebuild. The Hash Generator on ToolCraft lets you generate SHA-256 checksums right in the browser โ€” compare the hash before and after rebuild to confirm the file was actually replaced, not just touched.

Quick reference

  • Root cause: Native addon compiled for old Node.js ABI โ€” incompatible after upgrade (e.g., ABI 108 โ†’ 115 between v18 and v20)
  • Fix 1: npm rebuild
  • Fix 2: Delete node_modules + reinstall
  • Fix 3: Install build tools first (build-essential on Linux, Xcode CLI on macOS, Visual Studio Build Tools on Windows), then rebuild
  • Docker: Remove volume cache, rebuild image using npm ci with build tools in the image
  • Prevention: Pin Node.js version with .nvmrc

Related Error Notes