Skip to content

fix: add shell wrapper to resolve bun/node ABI mismatch#320

Open
wolfkevin wants to merge 2 commits intotobi:mainfrom
wolfkevin:fix/bun-node-abi-mismatch
Open

fix: add shell wrapper to resolve bun/node ABI mismatch#320
wolfkevin wants to merge 2 commits intotobi:mainfrom
wolfkevin:fix/bun-node-abi-mismatch

Conversation

@wolfkevin
Copy link

@wolfkevin wolfkevin commented Mar 8, 2026

Problem

When installed via `bun install -g`, `better-sqlite3` is compiled against bun's internal ABI (`NODE_MODULE_VERSION 141`). The hardcoded `#!/usr/bin/env node` shebang in `dist/qmd.js` then causes every command to fail on systems where `node` resolves to a standard Node.js binary (e.g. nvm-managed v22.x, module version 127):

```
Error: The module '.../better_sqlite3.node'
was compiled against a different Node.js version using NODE_MODULE_VERSION 141.
This version of Node.js requires NODE_MODULE_VERSION 127.
```

The README presents bun and npm as equivalent install options, so this is easy to hit. Fixes #319.

Fix

Replaces the hardcoded shebang with a `bin/qmd` shell wrapper that detects the install method via path and picks the matching runtime:

```sh
#!/bin/sh
DIR="$(cd "$(dirname "$0")/.." && pwd)"
case "$DIR" in
/.bun/) exec bun "$DIR/dist/qmd.js" "$@" ;;
*) exec node "$DIR/dist/qmd.js" "$@" ;;
esac
```

If the package is installed under `.bun/` (i.e. via `bun install -g`), it runs under bun — matching the ABI used to compile the native addon. Otherwise it falls back to node.

Also updates `package.json` to point `bin.qmd` at `bin/qmd` and adds `bin/` to the `files` array.

Note: this aligns with the direction already described in `CLAUDE.md` ("The `qmd` file is a shell script that runs compiled JS from `dist/`").

When installed via bun, better-sqlite3 is compiled against bun's ABI
(NODE_MODULE_VERSION 141). The previous hardcoded #!/usr/bin/env node
shebang caused ERR_DLOPEN_FAILED on systems where node resolves to a
standard Node.js binary (e.g. nvm-managed v22.x, module version 127).

Add a bin/qmd shell wrapper that prefers bun when available, falling
back to node. This ensures the runtime matches the ABI used during
native module compilation.

Fixes tobi#319
Using 'command -v bun' would prefer bun even for npm installs, potentially
causing the same ABI mismatch in reverse. Instead, check if the package
directory is under .bun/ to detect how it was installed and use the
matching runtime.
@wolfkevin wolfkevin force-pushed the fix/bun-node-abi-mismatch branch from 38eb8f1 to f8cdfdb Compare March 8, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bun global install fails when run with node: native module ABI mismatch (better-sqlite3)

1 participant