Claude Codeの埋め込みBunを端末で検査する
昨日、Claude Code の更新後にいつものスモークテストを流していて、起動時の挙動が少し変わった気がした。依存を増やした覚えはないのに、実行基盤まで入れ替わっているなら、見る場所は変わる。
先に結論を書くと、今の Claude Code は実行時に使う Bun の版数をバイナリから確認できる。Rust 由来のパス文字列も一緒に拾っておくと、少なくとも「Node を呼び出しているだけ」という前提で調査を始めずに済む。
Q. なぜランタイムを調べるのか
2026年7月の Bun の発表では、Claude Code v2.1.181 以降が Rust 版 Bun を使い、Linux の起動が10%速くなったと説明されている。全面移植は 11 日間、約50本の dynamic workflow で進め、既存の TypeScript テスト群をそのまま回したという。画面には出にくい変更でも、起動、子プロセス、モジュール解決で差が出たときの切り分け情報になる。
ログを集め始める前に、まず同梱バイナリを読むことにした。調査の入口として安い。
Q. 端末では何を実行すればいい?
次のスクリプトは claude が PATH にあることを前提に、埋め込み Bun の版数と Rust のソースパス文字列の件数を出す。macOS で Claude Code 2.1.215 に対して実行した。
#!/usr/bin/env bash
set -euo pipefail
claude_bin="$(command -v claude || true)"
if [ -z "$claude_bin" ]; then
echo "claude command not found" >&2
exit 1
fi
bun_version="$(LC_ALL=C strings "$claude_bin" |
sed -nE 's/^(Bun v[0-9][^[:cntrl:]]*)$/\1/p' | head -n 1)"
rust_paths="$(LC_ALL=C strings "$claude_bin" |
rg -o 'src/[[:alnum:]_./-]+\.rs' | wc -l | tr -d ' ')"
printf 'Claude binary: %s\n' "$claude_bin"
printf 'Embedded runtime: %s\n' "${bun_version:-not found}"
printf 'Rust source paths: %s\n' "$rust_paths"
if [ -z "$bun_version" ] || [ "$rust_paths" -eq 0 ]; then
echo "expected markers were not found" >&2
exit 2
fi
実行結果はこうなった。
Claude binary: /opt/homebrew/bin/claude
Embedded runtime: Bun v1.4.0 (macOS arm64)
Rust source paths: 563
strings の結果はバイナリに含まれる文字列であって、Rust のコード全体を復元しているわけではない。だからこれは厳密な来歴証明には使えない。それでも、版数と .rs パスが同じ実行ファイルから取れるので、調査対象の実体を取り違えないためには十分役立つ。
Q. 563件という数字は何を意味する?
563 はユニークなファイル数ではない。リンク時に残った重複を含む、マッチしたパス文字列の件数だ。ユニーク数が必要なら、パイプの末尾を sort -u | wc -l に替える。手元では223件だった。
ここで数を増やすこと自体に意味はない。更新前後で同じ検査を残し、Bun の版数だけが変わったのか、同梱物の構成まで動いたのかを比較する。CI の常時チェックより、更新直後の手動スモークテストに足すくらいが扱いやすいと思う。
別の話だけど、ランタイム移行の話を聞くと性能だけを追いがちだ。Bun の説明を読むと、移植の動機は use-after-free や double-free をコンパイラの検査へ寄せることにあった。体感の速さより、障害調査で再現しにくいクラッシュの母数が減る方が、チームには効くことが多い。
Q. この情報を障害対応でどう使う?
まずバグ報告に claude --version だけでなく、上の2行を添える。次に、更新直後だけ失敗したなら、同じプロンプトを別マシンと比較する前に、同梱 Bun の版数差を確認する。子プロセスやファイル監視が絡むなら特に早い。
Claude Code の更新は、CLI の機能差だけを見ていれば足りる時期ではなくなった。実行ランタイムもリリース境界として扱う。小さな検査だけど、原因調査の最初の30分を無駄にしないための記録になる。
参考: Bun公式: Rewriting Bun in Rust、Claude Code uses Bun written in Rust now