JavaScript

Bunランタイムとは?JavaScriptCoreで動く仕組みとNode.jsとの実行差・版の固定方法

Bunランタイムとは?JavaScriptCoreで動く仕組みとNode.jsとの実行差・版の固定方法

Bunを「V8ベースの高速ランタイム」と説明する記事は少なくありませんが、これは誤りです。Bunが積んでいるエンジンはAppleのJavaScriptCoreで、V8を使っているのはNode.jsとChromium系ブラウザのほうです。この違いは起動時間の傾向、対応しているデバッグ手法、Node.js向けネイティブアドオンの動き方にそのまま効いてきます。ここではランタイムとしてのBunの実体と、Node.jsとの実行差、そして本番で効く「版の固定」までを、公式ドキュメントとGitHub APIの実測値で整理します。インストール手順とコマンド一覧はBunとは?インストール(brew・curl)から使い方・コマンドまで解説にまとめてあります。

まとめ:Bunランタイムの要点

  • エンジンはV8ではなくJavaScriptCore。Bunは「V8のAPIをV8なしで実装する」方針を公式ブログで明示している
  • 実装言語は移行の途中。配布されている安定版1.3系はZigで書かれており、Rust化されたコードはmainブランチ側にある
  • Node.jsのドロップイン代替として設計されており、置き換えの可否は「Node.js互換APIをどこまで踏んでいるか」で決まる
  • 最新版はbun-v1.3.14(2026年5月13日公開)。更新チャネルはstableとcanaryの2系統で、LTSという名称のチャネルは公式ドキュメントに無い
  • 本番ではbun upgrade任せにせず、版を明示指定してインストールする

以降で、この4点の根拠と実際の操作を順に見ていきます。

Bunランタイムの実体|JavaScriptCore採用と実装言語の移行

「BunはV8ベース」が誤りである根拠

Bunの公式リポジトリoven-sh/bunのREADMEは、Bunランタイムを「a drop-in replacement for Node.js」と定義したうえで、”It’s written in Rust and powered by JavaScriptCore under the hood” と書いています。JavaScriptCoreはWebKit/Safariのエンジンで、V8とは別系統です。

裏付けはこれだけではありません。Bunは公式APIリファレンスにbun:jscというモジュールを持っており、これはJavaScriptCoreそのものを操作するための低レベルAPIです。さらに公式ブログには「How Bun supports V8 APIs without using V8」という記事があり、V8を使わずにV8のAPIを再実装しているという立場が明言されています。V8ベースであればこの記事は成立しません。

実務上の意味は明確です。V8前提のツールがそのまま動くとは限らない、という一点に尽きます。V8のヒープスナップショットのようにBun側が互換を用意している領域もありますが、V8の内部挙動に依存した最適化やプロファイリング手法を前提に設計すると、Bunでは想定どおりに動きません。ランタイムを差し替える判断の前に、依存しているツールがエンジンの何に触れているかを確認してください。

実装言語とバイナリ構成

実装言語は移行の最中にあり、ここは調べ方を間違えると逆の結論になります。GitHub APIのrepos/oven-sh/bun/languagesを引くとRustが42,063,838バイトで最大と表示され、Zigは1バイトも計上されません。READMEも「written in Rust」です。ところがこの2つはどちらも既定ブランチ(main)の状態しか示していません

実際に配布されている版を確認するには、タグのソースツリーを見ます。最新の安定版タグbun-v1.3.14src/配下は、.zigが1,290ファイルで.rsは1件も含まれていません。一方mainのsrc/.rsが1,516ファイルで.zigはゼロです。つまりいまbun upgradeで入る安定版はZigでビルドされたもので、Rustへの置き換えはmain側で進行中という状態です。実装言語を判断材料にするなら、languages APIやREADMEではなく、使用するタグのツリーを確認してください。なお2026年8月20日公開のBun 1.4で安定版もRust実装へ切り替わり、タグbun-v1.4.0src/配下は.rsが1,512ファイル・.zigがゼロになっています。

配布形態はbunという単一の実行ファイルです。ランタイム・パッケージマネージャ・テストランナー・バンドラが1つのバイナリに同梱されているため、Node.jsのように実行環境と周辺ツールを別々に入れる構成にはなりません。CIイメージを組むときは、この単一バイナリを1つ置けば足りる点が効いてきます。

Node.jsとの実行差|ドロップイン互換が成立する範囲

BunはNode.jsのドロップイン代替を掲げており、READMEでも起動時間とメモリ使用量の削減を設計目標として挙げています。ただし「置き換えられる」の中身は一様ではありません。判断は次の順で切り分けると早いです。

まず、純粋なJavaScript/TypeScriptと標準的なnode:組み込みモジュールだけで完結しているコードは、置き換えの成功率が高い領域です。BunはTypeScriptとJSXを追加設定なしで実行できるため、トランスパイル工程を前提にしたスクリプトはむしろ構成が簡素になります。

次に、ネイティブアドオンです。V8のC++ APIに直接依存したアドオンは、エンジンが違う以上そのままでは動きません。ここがBun移行で最初に詰まる箇所で、依存ツリーにネイティブモジュールが含まれているかを先に洗ってください。

最後に、運用系です。プロファイラ、APMエージェント、デバッガの一部はV8の内部インターフェースに接続して情報を取ります。本番監視をこれらに預けている場合、ランタイムを替えると観測手段ごと失う可能性があります。Node.js側の現行仕様と突き合わせるならNode.js 26の新機能・変更点とLTSスケジュールが対照になります。

結論として、CIのビルドスクリプトや開発時のタスクランナーから置き換えるのが最も安全で、ネイティブアドオンとAPMを抱えた本番プロセスを最初に替えるのは勧められません。

他のJavaScriptランタイム・ビルドツールとの守備範囲の違い

「BunとViteはどちらを使うべきか」という比較は、そもそも守備範囲が重なっていないため設問として噛み合っていません。Bunはサーバー側でコードを実行するランタイムを含み、Viteは開発サーバーとバンドルを担うビルドツールです。両者は競合ではなく併用できます。

ツール エンジン/実装 ランタイム パッケージ管理 バンドル
Bun JavaScriptCore/Zig(安定版) あり 内蔵 内蔵
Node.js V8/C++ あり npm等が別途 別ツール
Deno V8/Rust あり 内蔵 内蔵
Vite ビルドツール なし なし あり

選定の分かれ目は、エンジンとパーミッションの扱いです。V8を維持したままオールインワン構成が欲しいならDenoが該当し、権限設計まで含めた比較はDenoとFreshの開発環境セットアップで扱っています。逆に、既存のNode.jsプロジェクトの周辺ツールだけを速くしたい場合は、ランタイムを替えずにビルド層を差し替えるほうが影響範囲が小さく、Rust製ツールチェーンのOxcのような選択肢が合います。

ランタイム版の確認・固定・更新チャネル

稼働中の版を特定する

公式ドキュメントが案内する確認コマンドは2つあります。

bun --version
bun --revision

--versionはバージョン番号、--revisionはビルドのリビジョンまで返します。canaryを踏んでいる環境ではバージョン番号だけでは同一に見えることがあるため、不具合の切り分けではリビジョンまで取ってください。GitHub Releases APIで確認した最新の安定版タグはbun-v1.3.14で、公開日は2026年5月13日です。

版を固定してインストールする

本番環境やCIでは、暗黙の最新版追従を避けて版を明示します。公式のインストールスクリプトは、引数でタグを指定できます。

curl -fsSL https://bun.com/install | bash -s "bun-v1.3.3"

Windowsでは同じ指定をPowerShell側の引数で行います。

iex "& {$(irm https://bun.com/install.ps1)} -Version 1.3.3"

パッケージマネージャ経由で入れた場合は更新経路を混ぜないことが重要です。公式ドキュメントは、Homebrewで導入したならbrew upgrade bunを、Scoopならscoop update bunを使うよう明記しています。bun upgradeと混用すると管理主体が二重になり、どちらの版が起動しているのか追えなくなります。

stableとcanaryの切り替え

更新チャネルは2系統です。

bun upgrade --canary
bun upgrade --stable

canaryは未テストのビルドを取りに行く経路なので、再現待ちの不具合を検証する用途に限定し、検証が終わったら--stableで戻します。なお公式インストールドキュメントが案内する切り替え先はこのstableとcanaryだけで、LTSという名称のチャネルは記載されていません。Node.jsのような偶数版LTSを前提にした保守計画をそのまま持ち込むと、想定した長期サポート期間が存在しないことになります。Bunで長期運用するなら、チャネルに頼らず上記のタグ指定で版を固定し、更新時期を自社で決める運用にしてください。

よくある質問

BunはV8エンジンで動いていますか?

動いていません。BunのエンジンはJavaScriptCoreです。公式READMEが “powered by JavaScriptCore under the hood” と明記しており、公式ブログにも「V8を使わずにV8のAPIをサポートする方法」という記事があります。V8を使っているのはNode.jsとChromium系ブラウザです。

BunにLTS版はありますか?

公式インストールドキュメントが案内する更新チャネルはstableとcanaryの2系統で、LTSという名称のチャネルは記載がありません(2026年8月時点)。長期運用では、チャネル指定ではなくbun-v1.3.14のようにタグを指定したインストールで版を固定してください。

Bunのバージョンを固定するにはどうしますか?

インストールスクリプトにタグを渡します。macOS/Linuxはbash -s "bun-v1.3.3"、Windowsは-Version 1.3.3です。Homebrew経由で入れた環境ではbun upgradeを使わずbrew upgrade bunに統一し、更新経路を一本化します。

BunはViteの代わりになりますか?

代替関係にはありません。Viteは開発サーバーとバンドルを担うビルドツールで、Bunはランタイムを含むツールキットです。ViteをBun上で動かす併用構成が取れるため、どちらかを選ぶ問題ではなく、ランタイムを替えるのかビルド層を替えるのかという別々の判断になります。

Node.jsの実行が重いと感じたらBunに置き換えられますか?

コードが純粋なJavaScript/TypeScriptと標準的な組み込みモジュールで完結していれば、置き換えの成功率は高いです。一方、V8のC++ APIに依存したネイティブアドオンや、V8の内部インターフェースに接続するAPMエージェントを使っている場合は、そのままでは動きません。CIのビルドスクリプトなど影響範囲の小さい層から試すのが安全です。

関連記事

資料請求

RELATED POSTS 関連記事