Bun 1.4が公開された。
Node.js公式テストから新たに1,517件が通過し、2,900件を超える問題を修正。アイドル時のCPU使用率は最大5分の1、メモリ使用量は最大35%削減され、Linuxでは起動時間が半分になったという。
さらに、Bun本体はZigからRustへ移植された。
これだけでも、十分に大きなアップデートである。
だが、今回の発表で私が目を奪われたのは、そこではない。
- Playwrightなしのブラウザ操作
- node-ptyなしのターミナル操作
- sharpなしの画像処理
- Markdownの解析とレンダリング
- OSへ直接登録できるcron
- CPU、Heap、bundle解析のMarkdown出力
これは、どう見てもAI Agentの道具箱である。
もちろん、Bun公式は「AI Agent専用ランタイムになりました」と宣言しているわけではない。
個々の機能は、一般的なWebアプリケーションやCLIツールでも役に立つ。
しかし、それらを一つのランタイム上に並べてみると、見えてくる用途はあまりにもAgenticだ。
Playwrightなしでブラウザを操作する
最も目を引くのが、Bun.WebViewである。
Bun単体でWebページを開き、クリックし、スクロールし、JavaScriptを実行し、スクリーンショットを撮影できる。
await using view = new Bun.WebView({
width: 800,
height: 600,
});
await view.navigate("https://bun.sh");
await view.click("a[href='/docs']");
const title = await view.evaluate("document.title");
const screenshot = await view.screenshot();
await Bun.write("page.png", screenshot);
これだけである。
PuppeteerもPlaywrightも必要ない。
macOSではOS標準のWebKitを利用でき、macOS、Linux、Windowsでは、インストール済みのChrome、Chromium、Edgeも操作できる。
クリックやスクロールは単なるDOMイベントの注入ではなく、ブラウザから信頼されたユーザー入力として扱われる。必要ならChrome DevTools Protocolを直接呼び出すための逃げ道も用意されている。
なお、Bun.WebView自体は1.3.12で登場した機能だ。Bun 1.4の発表記事は1.3以降の更新をまとめたものなので、厳密には1.4で突然生えたわけではない。
それでも、現在のBunがどこへ向かっているのかを示す機能として、存在感は圧倒的である。
AI Agentにブラウザを操作させようとすると、通常はPlaywrightやPuppeteerを導入し、ブラウザ本体を用意し、Agent側へ操作用のToolを定義する。
Bunは、その最も面倒な部分をランタイムへ溶かし始めた。
ターミナル操作もランタイムに入った
ブラウザの次は、ターミナルである。
Bun.Terminalは、Bunに内蔵された擬似端末、いわゆるPTYだ。
JavaScriptからbashを起動し、文字を入力し、画面サイズを変更し、色付きの出力を読み取れる。Linux、macOS、Windowsに対応する。
const proc = Bun.spawn(["bash"], {
terminal: {
cols: 80,
rows: 24,
data(term, data) {
process.stdout.write(data);
},
},
});
proc.terminal.write("echo Hello from PTY!\n");
従来なら、ここでnode-ptyの出番だった。
しかし、Bunではそれすら必要ない。
AI Agentにコードを書かせるだけなら、通常のプロセス実行でも足りる。だが、対話型CLI、vim、htopなど、人間が端末上で操作することを前提としたプログラムまで扱わせるにはPTYが必要になる。
ブラウザを操作できる。
ターミナルも操作できる。
この二つがランタイム標準で揃った時点で、単なるNode.js互換環境という説明では足りなくなる。
画像、Markdown、cronまで揃っている
Bun.Imageは、画像の読み込み、リサイズ、回転、形式変換などを担当する。
公式の例では、画像をデコードし、リサイズして別形式へ変換する処理が、sharpより1.38倍高速だったとしている。
Agentがブラウザのスクリーンショットを取得し、その画像を縮小・変換して保存する。あるいは、画像を次のVisionモデルへ渡すために前処理する。
その工程までBunだけで完結する。
Bun.markdownは、MarkdownをHTMLへ変換するだけではない。
React要素やターミナル向けのANSI出力にも変換できる。GFMの表、取り消し線、タスクリスト、オートリンクにも対応する。
そしてBun.cron()は、Linuxのcrontab、macOSのlaunchd、Windowsのタスクスケジューラへジョブを登録する。
await Bun.cron(
"./worker.ts",
"30 2 * * MON",
"weekly-report"
);
Agentが処理を組み立てる。
動作を確認する。
そのまま定期実行へ登録する。
ここまで来ると、「AI Agentに必要なTool一式、ご用意しました」という印象を受けるのも無理はない。
プロファイルをMarkdownで出力する意味
今回、私が最もAgent時代らしいと感じたのは、ブラウザ操作でもターミナル操作でもない。
Bun 1.4では、CPUプロファイル、Heapプロファイル、bundle解析をMarkdownで出力できる。
bun --cpu-prof-md ./app.ts
bun --heap-prof-md ./app.ts
bun build ./src/index.ts --metafile-md=./dist/meta.md
CPUプロファイルには、処理時間を消費している関数、呼び出し元、呼び出し先、コールツリーなどが表形式で書き出される。
Heapプロファイルでは、メモリを保持しているオブジェクトや参照関係を追える。
bundle解析では、どのモジュールが出力サイズを膨らませ、どのimport経路から取り込まれたのかを確認できる。
従来、こうした情報はDevToolsや専用ビューアーで、人間がグラフを眺めながら読むものだった。
Bunは、それをMarkdownへ変換した。
つまり、そのままLLMへ食わせられる。
AI Agentにプログラムを実行させ、遅い箇所をプロファイルさせ、結果のMarkdownを読ませ、修正案を出させる。
bundleが肥大化したら、依存関係のレポートを読ませて原因を探らせる。
メモリが減らなければ、Heapプロファイルから保持元を追わせる。
Agentの目を良くするために、大がかりな専用Toolを作る必要がない。
観測結果をLLMが読めるテキストへ落とす。
この設計は、かなり露骨にAI時代を意識しているように見える。
Claude CodeはすでにRust版Bunを使っていた
Bun 1.4では、Bun本体がZigからRustへ移植された。
ランタイムの全面移植だけでも大事件だが、興味深いのは、Claude Codeが数か月前からRust版Bunを使用していたという点である。
Claude Codeのような大規模かつ長時間動作するアプリケーションでは、Bun 1.4によってCPU使用率が大きく低下した。
公式発表によると、p99は24%から10%へ、p50は5.8%から2.5%へ下がった。
Claude Codeは、まさにAgenticなCLIアプリケーションである。
大量のJavaScriptを動かし、ターミナルを操作し、ファイルを読み書きし、Tool Callを繰り返しながら長時間稼働する。
Bun 1.4の改善は、短いベンチマークスクリプトを速くするだけのものではない。
すでにAI Agentの実運用環境で鍛えられていた。
そう考えると、CPU使用率やメモリ回収、PTY、Markdownプロファイルといった更新が、一つの線でつながって見えてくる。
Node.js互換性も現実的な水準へ
Bunがどれだけ独自機能を増やしても、既存のnpm資産が動かなければ、実用上は別世界のランタイムになってしまう。
そこで重要になるのが、Node.js互換性である。
Bun 1.4では、Node.jsの公式テストから新たに1,517件が通過するようになった。
node:http、node:fs、node:cluster、node:timers、node:zlib、node:vm、node:streamは、Node.js自身のテストの97%を通過。node:quicは99%、node:events、node:trace_events、node:sqliteは100%としている。
Playwright、Vitest、OpenTelemetry、Datadogのdd-traceなども、Bun上での対応が進んだ。
まだ100%互換ではない。
しかし、「速いが、何かが動かないかもしれない実験的ランタイム」から、「既存のNode.jsアプリケーションを現実的に移せる実行基盤」へ近づいているのは確かだ。
Agent開発では、モデルの能力以上にToolの安定性が効く。
ファイル操作、HTTP、Stream、Worker、子プロセスなどの微妙な非互換は、Agentの不可解な失敗として表面化する。
だからこそ、地味な互換性改善が重要になる。
新機能の派手さを支えているのは、1,517件のテストという、実に泥臭い仕事である。
15個の依存関係が0個になる
Bun公式は、今回の機能群を象徴する例として、15個の依存関係がBun 1.4では0個になる図を掲載している。
そこには、次のようなパッケージが並んでいる。
- sharp
- puppeteer
- marked
- node-cron
- node-pty
- concurrently
- npm-run-all
- serve-static
- json5
- fast-xml-parser
- tar
これらを単に同梱したという話ではない。
JavaScriptアプリケーションを組み立てるたびにnpmから集めていた基盤機能を、ランタイムが標準機能として引き受け始めた。
Node.jsの文化では、小さなパッケージを組み合わせることが強みだった。
一方で、依存関係の増加、更新停止、脆弱性、破壊的変更、インストール時間、環境差といった問題も生んできた。
AI Agentは、自分で必要なパッケージを選び、インストールし、設定することもできる。
しかし、選択肢が増えるほど、失敗経路も増える。
ブラウザ操作も、PTYも、画像処理も、Markdownも、定期実行も、同じランタイムの標準APIで扱えるなら、Agentが生成すべきコードは短くなり、依存関係も減り、環境再現性は上がる。
Agent時代には、「何でも選べること」よりも、「最初から安全な道具が揃っていること」の価値が大きくなるのかもしれない。
BunはAgent Harnessを薄くする
現在のAI Agentは、LLMの外側に大きなHarnessを必要とする。
ブラウザ操作用Tool。
ターミナル操作用Tool。
画像処理用Tool。
スケジューラー。
プロファイラー。
依存関係の管理。
OSごとの差異を吸収する処理。
私たちは、それらを組み合わせて「Agentが働ける環境」を作っている。
Bun 1.4が示した方向は、そのHarnessの一部をランタイム側へ吸収するものだ。
Agent Harnessが消えるわけではない。
権限制御、停止条件、承認フロー、Context管理、Tool Callの検証など、ランタイムだけでは解決できない問題は残る。
それでも、Agentが現実のソフトウェアを操作するための低層Toolは、かなり薄くできる。
BunはNode.jsを倒そうとしているだけではない。
npmから必要な道具を集め、開発環境を組み立てるという、JavaScript開発の前提そのものを変えようとしているように見える。
まずはフラッシュ、実機検証は後日
今回は、Bun 1.4の発表内容を読んだ時点でのファーストインプレッションである。
Bun.WebViewがPlaywrightをどこまで代替できるのか。
Windows上でEdgeを安定して操作できるのか。
Bun.TerminalをAgentから扱ったとき、対話型CLIはどこまで制御できるのか。
スクリーンショットの取得、画像処理、Markdownレポートの解析までを一つのワークフローとして組めるのか。
その実用性については、まだ確認していない。
後日、実際にWindows環境へ導入し、Agent用Toolとして触ってみたい。
ただし、現時点でも一つだけは言える。
Bun 1.4は、単なる高速なJavaScriptランタイムではない。
ブラウザを見て、ターミナルを叩き、画像を扱い、実行結果をMarkdownで読み、仕事を定期実行する。
AI Agentに必要なTool一式を、ランタイムが自分で揃え始めた。
Bun 1.4は、Agent時代のJavaScript実行基盤がどのような姿になるのか、その一つの答えを先に見せている。
参考・出典
本稿の執筆にあたり、以下の資料を参照しました。
- Bun Blog「Bun 1.4」
Bun 1.4のNode.js互換性、性能改善、Rustへの移植、Bun.WebView、Bun.Terminal、Bun.Image、Bun.markdown、Bun.cron()、Markdown形式のプロファイル出力など。
https://bun.com/blog/bun-v1.4


