こんにちは、みねです。
「Bun 1.3 を本番採用しても大丈夫か?」——直近の社内技術選定や ADR レビューで、何度かこの問いが上がりました。ベンチで「N 倍速い」と聞けば心が動きますが、本番に乗せた瞬間に「ネイティブアドオンが動かない」「観測性ツールが繋がらない」で巻き戻すのは避けたい。
この記事は、Bun 1.3 を CTO / Tech Lead が ADR に貼れる粒度で判断するための 4 軸比較と、全置換ではなく段階的に本番へ寄せていくハイブリッド運用の現実解を整理します。
TL;DR
- 判断軸は 4 つに絞る: パフォーマンス / Node.js 互換性 / エコシステム / 運用リスク
- 全置換よりハイブリッド: CI・スクリプト → 開発環境 → 一部マイクロサービス → 全置換、の段階導入が現実解
- 数値断言は警戒: 「N 倍速い」系は 公式値(Bun 自己ベンチ) か 経験則 かを区別。I/O bound では差が縮む
この記事でできるようになること
- Bun 1.3 の採用可否を 4 軸(パフォーマンス・互換性・エコシステム・運用)で評価できる
- ADR に転載できる「採用判断比較表」を手元に置ける
- 「本番一発置換」を避け、段階的にリスクを切り離す導入計画を引ける
対象読者
- バックエンド / Tech Lead / CTO(経験 5 年以上、技術選定の意思決定責任あり)
- 既に Node.js で本番運用していて、Bun 採用案を上長や経営に説明したい
- 失敗事例とロールバック条件まで把握しておきたい
この記事でやらないこと
- Bun のインストール手順(Bun 公式に譲る)
- 全 API のリファレンス比較
- フロントエンド(ブラウザ)での Bun 利用ケース
1. なぜいま Bun 1.3 か
1.1 Bun 1.3 GA の位置付け
Bun は Zig 製の JavaScript / TypeScript ランタイムで、bun run / bun install / bun test / bun build を 1 バイナリで提供します(Bun 公式)。1.3 系では Node.js 互換 API のカバレッジ拡充、テストランナー強化、バンドラー最適化が進みました(Bun GitHub Releases)。
ポイントは「速度」ではなく「スコープ」です。Node.js が標準ライブラリの拡充に時間をかける間、Bun は package manager・test runner・bundler を含めた開発者ツール一式を統合してきました。
1.2 Node.js / Deno / Bun の役割の重なりと違い
| 観点 | Node.js | Deno | Bun |
|---|---|---|---|
| 設計思想 | 安定性・互換性最優先 | セキュア・Web 標準寄り | 速度・開発者体験統合 |
| パッケージ | npm | npm + JSR + URL | npm 互換 + bun レジストリ |
| 標準ツール | 別ツール(npm/jest/webpack) | 内蔵 | 内蔵 |
| 実装言語 | C++ / JS | Rust | Zig |
3 者は完全な代替関係ではなく重なりがあります(Node.js 公式、Deno 公式、Bun 公式)。Bun を採用しても Node.js 資産は捨てられないことがほとんどで、後述の §6 で扱う「ハイブリッド運用」が前提になります。
2. 評価軸 1: パフォーマンス
2.1 起動時間と HTTP throughput(公式値)
Bun 公式ベンチでは、起動時間・fetch ベース HTTP サーバーの throughput・bun install 速度で Node.js / npm を上回ると報告されています(公式値: Bun ベンチマーク)。bun install は並列ダウンロードと OS レベルの最適化(macOS でのハードリンク、Linux での io_uring 利用など)が効きます。
ただし「N 倍速い」という見出しを ADR に貼ると、後で 再現条件を問われて困ります。本番採用の判断では「自社の代表的ユースケースでベンチを取り直す」が鉄則です(経験則)。
2.2 I/O bound では差が縮む
CPU bound なテンプレートエンジン処理や JSON パースでは差が出やすい一方、DB アクセス・外部 API 呼び出しが律速になるワークロードでは Node.js との差は実用上ほぼ見えません(経験則)。p99 レイテンシのうちランタイムが占める比率を測ってから判断するのが安全です。
2.3 ベンチ条件チェックリスト
採用判断のためにベンチを取るときは、最低限これを揃えます。
- 同一マシン・同一カーネル・同一 CPU 周波数固定
- ウォームアップ後の定常状態で測定
- 同一バージョンの依存パッケージ(
package-lock.json/bun.lockb) - p50 / p95 / p99 を取り、平均だけで判断しない
3. 評価軸 2: Node.js 互換性
3.1 標準ライブラリのカバレッジ
Bun は node:fs / node:http / node:crypto / node:worker_threads などの node:* 名前空間 API をネイティブに実装しています(Bun 互換性ドキュメント)。1.3 系では未実装エッジケースが大きく減りましたが、主要 npm パッケージの大半は動くものの、一部のライブラリ(特にネイティブアドオンを呼ぶもの)は要検証です(経験則)。
「Node.js 互換 X%」のような単一の数値は、Bun 自身も Node.js 自身も公式に出していません。ADR では 「主要パッケージは動作確認済、ネイティブアドオン依存は要検証」 のような動詞ベースの記述にとどめるのが安全です。
3.2 ネイティブアドオン(node-gyp)の現状
node-gyp ベースのネイティブアドオンは、Bun 1.3 で Node-API(N-API)対応が進みました(Bun GitHub Releases)。ただし全ての C++ アドオンが透過的に動くわけではなく、bcrypt / sharp / DB ドライバーなど実際に使うものは個別に動作検証してください。互換性の有無で本番事故が起きやすい領域です。
3.3 採用前の互換性チェックリスト
採用前に一度回しておくと、後悔の確率が下がります。
package.jsonのdependenciesをbun installし直しbun testで既存テストがそのまま通るか- ネイティブアドオン(
bcrypt,sharp,node-canvas, DB ドライバー)が起動するか - APM / ロギングエージェント(Datadog, New Relic, Sentry など)の Node.js 用 SDK が動くか
- プロセスマネージャ(PM2)や systemd ユニットの起動コマンドが Bun でも成立するか
4. 評価軸 3: エコシステム
4.1 npm 互換と Bun 独自 API
bun install は npm レジストリ互換で、ほとんどの npm パッケージはそのまま導入できます(npm 公式)。package.json も既存のまま使えます。
一方で Bun 独自 API(Bun.serve, Bun.file, Bun.password, Bun.S3Client など)は Web 標準寄りに設計されていて魅力的ですが、これに深く依存すると Node.js への退避路を失うので、本番コードでは「Web 標準 API があるならそちらを優先」が安全です。
4.2 Web 標準(WinterCG)寄りの設計
fetch / Request / Response / URL などは Web 標準 API として共通実装されています(WinterCG)。Cloudflare Workers / Deno / Bun の間で移植性を持たせたいなら、Web 標準 API で書いておくと将来のランタイム乗り換えコストが下がります(経験則)。
4.3 主要フレームワークとの相性
| フレームワーク | Bun 相性 | 備考 |
|---|---|---|
| Hono | 優 | Web 標準 API ベースで Bun と親和的 |
| Express | 良 | 動くが Bun.serve のほうが性能を引き出せる |
| Next.js | 条件付き良 | bun run dev は動くが、ネイティブアドオン起因の不具合は要検証 |
| Fastify | 良 | 多くのプラグインが動作 |
| NestJS | 条件付き良 | 一部デコレーター挙動の差に注意 |
5. 評価軸 4: 運用リスク(採用判断比較表)
5.1 観測性
OpenTelemetry の Node.js SDK は Bun でも基本的に動作しますが、自動計装(auto-instrumentation)の一部は Node.js のフックに依存しているため、計装漏れがないかは個別に検証が必要です(経験則)。Datadog / New Relic / Sentry も同様で、「動く」と「すべての機能が動く」は別物です。
5.2 コンテナ運用
公式 Docker イメージ oven/bun が提供されています(Bun Docker Hub)。Node.js Alpine イメージと比較して、Bun の Distroless / Slim 版はサイズが大きい場合がある一方、ビルド時に依存ツール(npm/pnpm)を入れる必要が減るので、最終イメージは同等〜小さくなることが多いです(経験則、構成依存)。
5.3 採用判断比較表(ADR 用)
ADR にそのまま貼れる粒度の比較表です。
| 観点 | Bun 適 | 条件付き | Bun 不適 |
|---|---|---|---|
| CI / Lint / Test | 全般に適。bun test の起動・実行が高速 | — | — |
| 開発環境(dev サーバー) | フロントの dev / Hono / Fastify | Next.js(プラグイン依存) | ネイティブアドオン重依存 |
| API サーバー(HTTP) | Web 標準 API 中心、I/O 軽量 | Express + 標準ミドルウェア | gRPC ネイティブ重依存 |
| データ処理ジョブ | CPU bound のスクリプト | DB 重接続(ドライバー検証要) | レガシー C++ 拡張依存 |
| エッジ / 短命プロセス | 起動時間短く有利 | — | — |
| 観測性必須の本番 | OTel 手動計装で問題なし | 自動計装の検証が前提 | 自動計装が必須要件のサービス |
5.4 ロールバック条件と SLA
本番採用するときは「何が起きたら Node.js に戻すか」を ADR に書き残しておきます。
- p99 レイテンシが Node.js 比で +20% 以上劣化したまま 2 週間(経験則、サービス依存)
- 互換性起因のクラッシュが週 1 件以上
- APM の主要メトリクス(Apdex / エラー率)が観測不能になる
- セキュリティパッチの適用ラグが Node.js LTS より明らかに長い
6. ハイブリッド運用の現実解
6.1 段階 A: CI / Lint / Test runner(低リスク・効果大)
最初に Bun を入れるべきは CI です。本番ワークロードに触れず、bun install / bun test の高速化メリットが直接効きます。万が一動かないテストがあっても、Node.js にフォールバックすれば済みます。
6.2 段階 B: 開発・E2E 環境
dev サーバー / E2E 環境で bun run を試します。ここで互換性問題(特にネイティブアドオン)が顕在化するので、本番投入前の 互換性検証フェーズとして位置付けます。
6.3 段階 C: 一部マイクロサービス本番
最初は 新規・低トラフィック・ステートレス なサービスから。観測性とロールバック手順を §5 でリストアップしたチェックリストで整えてから投入します。
6.4 段階 D: 全置換
ここに進む前提条件: §6.1〜§6.3 を 3 ヶ月以上回し、互換性問題ゼロ・観測性すべてのメトリクス取得 OK・ロールバック演習成功、の 3 点が揃ってから。焦って D に進む合理的理由は通常ない、というのがハイブリッド運用の核です(経験則)。
段階の判断フローは記事の diagram 画像にもまとめています。
7. 失敗パターンと回避策
7.1 互換性の罠
「ローカルで動いた」を本番に持ち込むと、ネイティブアドオン・APM SDK・カスタム Node.js フラグ(--inspect, --max-old-space-size など)の差で事故ります。互換性検証は本番相当の構成(同じ Docker イメージ、同じ依存バージョン)で実施します(経験則)。
7.2 パッケージマネージャ二重化問題
package-lock.json と bun.lockb が共存する状態は CI を不安定にします。Bun に寄せるなら lockfile を 1 本化し、CI スクリプトでも bun install --frozen-lockfile のように固定します。
7.3 観測性ツール未対応のまま本番投入
「ベンチが速いから」で本番投入し、APM のメトリクスが半分しか取れていなかった、という事故が一番怖い類型です。観測性が満たされていなければ §6.3 には進まないを守ります。
8. ADR テンプレート(offer 連動)
社内の ADR にそのまま貼れる粒度の雛形です。§5.3 の比較表とセットで使ってください。
# ADR: Bun 1.3 採用方針
## Context
- 既存ランタイム: Node.js LTS
- Bun 1.3 GA を受けて採用検討
## Decision
- 段階 A(CI / Lint / Test)で Bun を採用
- 段階 B(開発環境)で互換性検証
- 段階 C(一部本番マイクロサービス)への昇格は次の Q で再評価
## Rationale
- §2 パフォーマンス: 自社代表ユースケースで p95 改善を確認
- §3 互換性: ネイティブアドオン X / Y / Z の動作確認済
- §4 エコシステム: Web 標準 API 中心の設計に整合
- §5 運用: OTel 手動計装で観測性確保、ロールバック手順整備済
## Consequences
- ロールバック条件: p99 +20% 劣化 2 週継続、または APM 主要メトリクス欠損
- 監視: 段階 C 投入から 1 ヶ月の集中監視期間
FAQ
Q1. Bun 1.3 を本番採用しても問題ないか?
用途次第です。CI / Lint / Test runner(段階 A)はリスクが小さく効果が大きいので、ほぼ常に「採用してよい」と言えます。一方で、ネイティブアドオン依存・APM 自動計装必須のサービスを段階 D(全置換)でいきなり Bun にするのは推奨しません。本記事の §6 のハイブリッド運用、特に段階 A→B→C→D の順序を踏むのが安全です。
Q2. Node.js から Bun に乗り換えるべきか?
「乗り換える」より「両方使う」が現実的です。Node.js LTS の安定性と Bun の開発体験を併用し、ワークロード特性に応じて選びます。Web 標準 API(fetch / Request / Response)でコードを書いておくと、将来どちらに寄せても移行コストが小さくなります。
Q3. bun install と pnpm / npm の併用は可能か?
技術的には可能ですが、lockfile が二重化すると CI が不安定になります。プロジェクト単位で 1 本化するのが推奨です。CI で bun install、ローカルで pnpm install のような併用は、依存解決アルゴリズムの違いで再現性問題を生むことがあるので避けます。
Q4. 観測性ツール(OpenTelemetry / Datadog)は使えるか?
OTel / Datadog / New Relic / Sentry の Node.js 用 SDK は Bun でも基本動作します。ただし自動計装の一部は Node.js のフックに依存しているため、計装漏れがないかを本番投入前に確認してください(経験則)。手動計装ベースで設計しておくと安全です。
Q5. ロールバック判断の基準は?
ADR にあらかじめ明記しておきます。例: 「p99 レイテンシが Node.js 比で +20% 以上劣化が 2 週間継続」「互換性起因のクラッシュが週 1 件以上」「APM の主要メトリクスが観測不能」。1 つでも該当したら段階を 1 つ戻す(C → B → A)運用がシンプルです。
まとめ
Bun 1.3 は「速い」だけのランタイムから、開発者ツールを統合した代替ランタイムへと成熟しました。ただし「速い → 全置換」はハイリスクで、段階 A(CI)→ B(開発)→ C(一部本番)→ D(全置換) の順で進めるのが現実解です。
本記事の §5.3 採用判断比較表と §8 ADR テンプレートは、社内の意思決定文書にそのまま転載できる粒度で書きました。読者のチームで採用検討に入るときの叩き台にしてください。
採用判断の壁打ち相手が必要なら、お気軽にご相談ください。
関連記事
- Node.js のセキュリティリリース運用 — Bun を入れても Node.js LTS の運用知識は必要
- Wasm はサーバー実装で本当に効くのか — 別の代替ランタイム選択肢としての比較
- Server vs Client Components の判断基準 — Bun + Next.js を考える際の前提
- Technology Radar の作り方|30分会議テンプレ付 — Bun の Adopt / Trial / Assess 判定を組織運用に乗せるフレーム
