TL;DR
- Bunは
node-gyp依存のネイティブモジュールをNode.js互換レイヤーでビルドするが、環境によって失敗する - 原因は主に3つ: Python/ビルドツール未設定、Bunバージョンの互換性問題、ネイティブモジュール自体の非対応
- Bun内蔵APIへの置き換えで根本解決できるケースが多い
環境
- OS: macOS 15 (Sequoia) / Ubuntu 24.04 LTS
- Bun: v1.2.x
- 再現日: 2026-03-23
問題の症状
bun installを実行した際に、以下のようなエラーが出てインストールが完了しない。
$ bun install
bun install v1.2.5
error: Failed to build native module "bcrypt"
node-gyp rebuild
gyp ERR! build error
gyp ERR! stack Error: not found: make
gyp ERR! stack at getNotFoundError
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/which/which.js:16:10
または別のパターン:
$ bun install
error: ModuleNotFoundError: No module named 'distutils'
gyp ERR! configure error
gyp ERR! stack Error: Could not find any Python installation to use
さらに別のケース:
$ bun install sharp
error: Failed to build native module "sharp"
CC(target) Release/obj.target/nothing/../node-addon-api/nothing.o
../src/common.cc:16:10: fatal error: 'vips/vips8' file not found
原因
node-gypはNode.jsのネイティブアドオン(C/C++拡張)をビルドするためのツールです。BunはNode.jsとの互換性を保つためにnode-gypを内部的に呼び出しますが、以下の理由でビルドが失敗します。
原因1: ビルドツールチェーンの不足
node-gypはC/C++コンパイラとPythonを必要とします。macOSではXcode Command Line Tools、LinuxではGCCとmakeが必要です。Python 3.12以降でdistutilsが標準ライブラリから削除されたことも原因になります。
原因2: Bunバージョンの互換性問題
Bunのnode-gyp互換レイヤーは急速に改善されていますが、一部のネイティブモジュールが要求するNode.js APIをBunがまだ実装していないケースがあります。
原因3: ネイティブモジュール固有の依存
sharp(libvips)、canvas(Cairo)など、システムライブラリに依存するモジュールは別途インストールが必要です。
解決方法
方法1: ビルドツールチェーンを正しく設定する(最も多い原因)
macOS:
# Xcode Command Line Toolsをインストール
xcode-select --install
# Python 3のsetuptoolsをインストール(distutils代替)
pip3 install setuptools
# 確認
python3 --version # Python 3.12+
make --version # GNU Make
Ubuntu/Debian:
# ビルドに必要なパッケージを一括インストール
sudo apt update
sudo apt install -y python3 make g++ python3-setuptools
# Python 3.12+の場合
pip3 install setuptools
インストール後に再実行:
bun install
# => 成功
方法2: Bun内蔵APIで代替する(根本的な解決)
Bunは多くのネイティブモジュールの機能を内蔵APIとして提供しています。node-gyp依存を完全に排除できるケースが多いです。
| node-gypが必要なパッケージ | Bun内蔵の代替 | 移行方法 |
|---|---|---|
better-sqlite3 |
bun:sqlite |
import { Database } from "bun:sqlite" |
node-ffi-napi |
bun:ffi |
import { dlopen } from "bun:ffi" |
bcrypt |
Bun.password |
await Bun.password.hash(password) |
補足:
jestやnode-fetch自体はnode-gypを必要としませんが、Bunではbun:testや組み込みfetchで代替でき、依存ツリーを大幅に削減できます。間接的なネイティブ依存を減らす効果があります。
具体例: better-sqlite3をbun:sqliteに置き換え
// Before: better-sqlite3(node-gyp必要)
import Database from 'better-sqlite3';
const db = new Database('mydb.sqlite');
const row = db.prepare('SELECT * FROM users WHERE id = ?').get(1);
// After: bun:sqlite(node-gypビルド不要)
import { Database } from 'bun:sqlite';
const db = new Database('mydb.sqlite');
const row = db.prepare('SELECT * FROM users WHERE id = ?').get(1);
// APIがほぼ同一なので、importの変更だけで済む
具体例: bcryptをBun.passwordに置き換え
// Before: bcrypt(node-gyp必要)
import bcrypt from 'bcrypt';
const hash = await bcrypt.hash('password123', 10);
const match = await bcrypt.compare('password123', hash);
// After: Bun.password(node-gypビルド不要)
const hash = await Bun.password.hash('password123', {
algorithm: 'bcrypt',
cost: 10,
});
const match = await Bun.password.verify('password123', hash);
方法3: システムライブラリをインストールする(sharp等の場合)
sharpやcanvasのようにシステムライブラリに依存するモジュールは、そのライブラリ自体のインストールが必要です。
# sharp の場合(libvips)
# macOS
brew install vips
# Ubuntu
sudo apt install -y libvips-dev
# 再インストール
bun install sharp
# canvas の場合(Cairo)
# macOS
brew install pkg-config cairo pango libpng jpeg giflib librsvg
# Ubuntu
sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
動作確認
解決後は以下のように正常にインストールが完了します。
$ bun install
bun install v1.2.5
Resolving dependencies... done.
Downloading packages... done.
+ bcrypt@5.1.1
+ sharp@0.33.5
128 packages installed [1.24s]
bun:sqliteに切り替えた場合はビルドステップ自体がなくなるため、インストール時間が大幅に短縮されます。
$ bun install
bun install v1.2.5
Resolving dependencies... done.
87 packages installed [0.31s] # ネイティブビルドなしで0.3秒
よくある質問
Q: --backend=copyfileオプションは効果がある?
bun install --backend=copyfileはファイルコピー方式を変更するオプションで、node-gypのビルドエラーには効果がありません。ビルドツールチェーンの問題かBun内蔵APIへの切り替えで対処してください。
Q: bun installは成功するが実行時にエラーが出る
ネイティブモジュールがBunのNode.js互換レイヤーと相性が悪い場合があります。切り分けとしてnodeコマンドで直接実行して動作するか確認し、Bun固有の問題であればBun内蔵APIへの移行を検討してください。Bunの互換性ドキュメントも参照すると役立ちます。
Q: CI/CD環境(GitHub Actions等)でのみ失敗する
CI環境にはビルドツールがプリインストールされていない場合があります。setup-bunアクションの前にビルドツールをインストールしてください。
# .github/workflows/ci.yml
- name: Install build tools
run: sudo apt-get install -y python3 make g++
- uses: oven-sh/setup-bun@v2
- run: bun install
Q: Apple Silicon (M1/M2/M3/M4) 固有の問題はある?
Apple Silicon MacではRosetta 2を経由してx86_64向けのネイティブモジュールをビルドしようとして失敗するケースがあります。以下を確認してください。
# Bunがarm64版かどうか確認
file $(which bun)
# => .../bun: Mach-O 64-bit executable arm64 ← arm64ならOK
# Homebrewがarm64版か確認(/opt/homebrew ならarm64)
which brew
# => /opt/homebrew/bin/brew ← OK
# => /usr/local/bin/brew ← x86_64版(再インストール推奨)
arm64版のBunとHomebrewを使っていれば、ほとんどのネイティブモジュールは問題なくビルドできます。
参考リンク
- Bun公式ドキュメント
- node-gyp GitHub リポジトリ(インストール要件の詳細)
- Bun Node.js互換性一覧
- Bunのセットアップから本番運用まで網羅したガイドも参考にしてください: Bun完全ガイド2026
まとめ
bun installでnode-gypビルドが失敗する場合、まずビルドツールチェーン(Python + make + コンパイラ)の設定を確認し、可能であればBun内蔵APIへの移行を検討しましょう。Bunはbun:sqlite、bun:ffi、Bun.passwordなど、多くのネイティブモジュールの代替を提供しており、ビルド依存を排除して高速なインストールを実現できます。