✍️ 필사 모드: Bun 回顧 2026 — 1.0 GA の約束と現実、ランタイム・バンドラー・パッケージマネージャー・テストランナー・シェルまで(Bun 2 時点での正直な評価)
日本語プロローグ —— 2023 年の約束、2026 年の請求書
2023 年 9 月、Bun 1.0 が GA で出たときの空気を覚えている。デモは衝撃的だった。bun install は npm install より 25 倍速く、bun test は Jest より 13 倍速く、bun run は Node より 4 倍速い起動。Twitter にはそのチャートが溢れた。半分は「Node はもう終わりだ」と言い、もう半分は「これは Yarn 1.0 モーメントの再来にすぎない」と言った。
2026 年 5 月。請求書を読む時間だ。
Bun は約束を半分ほど守った。しかしその半分は、私たちが期待していた半分とは違う半分だった。
bun install は本当に速い —— 約束どおり。bun test も速い。Bun.serve も実際に軽くて速い。しかし 「本番で Node を置き換える」というシナリオは稀だ。 2026 年中盤の正直な絵はこうだ。
- toolkit としての Bun は広く採用されている ——
bun install、bun test、Bun shell。CI 時間が半分になる。 - runtime としての Bun はまだ niche —— Bun.serve で作った小さな API ゲートウェイ、エッジワーカー、社内ツール。大規模モノリスが Bun に移ったという話はほぼ聞かない。
- Node 22+ が意外と良い守備をした ——
node --experimental-strip-types、node:test、node --watch、native fetch。Node は Bun が投げたボールを自陣で受け止めた。
この記事は 1.0 GA から 2 年半の 正直な回顧 だ。何が over-deliver し、何が broken promise で、どこで Bun が正しく、どこで Node がいまだに正しいのか。
1 章 · Bun ランタイム —— Zig + JavaScriptCore の最初の賭け
約束
Bun は最初から 3 つの賭け をした。
- Zig で書き直す —— V8 と Node 自身の C++ グルーの上に立つ Node とは違い、ランタイム自体を Zig で書いて起動時間とメモリフットプリントを小さくする。
- V8 ではなく JavaScriptCore (JSC) —— Safari が使うエンジン。起動とメモリで V8 より軽いというのが一般的な評価。
- Node API 互換 ——
fs、http、path、cryptoなどの Node モジュールをそのままサポート。約束は「Node プロジェクトをそのまま放り込んでも動く」。
この組み合わせで Bun は「ドロップイン置き換え」を狙った。
現実 —— ランタイム速度
ベンチマークは一貫して Bun が Node より速いと言う。しかし どこで速いか が重要だ。
コールドスタート ("console.log"):
Node 22: 35~60ms
Bun 1.2: 10~20ms
Deno 2: 25~40ms
HTTP スループット (単純エコー、シングルコア):
Node 22 (http): 80k req/s
Node 22 (uWebSockets) 280k req/s
Bun.serve: 250~310k req/s
Hono on Bun: 220~280k req/s
Deno serve: 200~240k req/s
SQLite クエリ (100 万行、単純 select):
better-sqlite3 (Node): 4.2s
bun:sqlite: 1.6s
確かに速い。しかし 差の形 を見よう。
- 起動時間 2~3 倍: AWS Lambda のような cold-start に敏感なワークロードで意味がある。普通の long-running サーバーでは無関係。
- HTTP スループット: Node がデフォルトの
httpモジュールではなく uWebSockets や fastify を使うと差は大幅に縮まる。公平な比較は「default vs default」ではなく「optimized vs optimized」だ。 - SQLite: 本当に差がある領域。
bun:sqliteは FFI で SQLite を直接呼んで N+1 を削るのが効いている。明確な win。
要点: Bun が速い理由は「JS の実行が速い」ではなく「I/O と native インターフェースが軽い」側だ。 だから CPU バウンドな JS コードでは Node と大差ない場合が多い。
現実 —— Node 互換性
Bun は 1.0 時点で「Node 互換 90% 以上」と広告していた。2026 年中盤の体感はこうだ。
| 領域 | 互換ステータス | 使えるか |
|---|---|---|
fs、path、os、util | ほぼ完全 | はい |
http、https、url | ほぼ完全 | はい |
crypto | ほぼ OK、一部 legacy API で差 | はい |
child_process | ほぼ OK | はい |
worker_threads | OK | はい |
cluster | 部分、edge case で差 | 注意 |
| Native addons (N-API) | 広く対応、一部未対応 | はい (おおむね) |
vm モジュール | 一部オプション欠落 | 注意 |
inspector (debugger プロトコル) | 部分対応 | 注意 |
async_hooks | 部分 —— APM ツール互換に影響 | 注意 |
process.binding 内部 API | 未サポート (意図的) | いいえ |
小さなサービスではほぼ問題ない。しかし APM (Application Performance Monitoring) エージェント、OpenTelemetry の auto-instrumentation、legacy native addon ではいまだに壊れる。New Relic や Datadog などの主要 APM が公式に Bun をサポートしたのは 2025 年末で、一部の instrumentation はいまだに部分対応のままだ。
「Node コードがそのまま動く」は小さなコードベースでは真、大きなコードベースでは半分真。 壊れるのはビジネスコードではなく 周辺インフラ (tracing、profiler、debugger) の側だ。
2 章 · bun install —— 最も明確な win
すべての領域の中で 最も議論の余地が少ない win が bun install だ。
ベンチマーク
hot cache、中規模 repo (約 800 deps):
npm install: 18s
yarn install: 9s
pnpm install: 5s
bun install: 1.6s
cold cache、同じ repo:
npm install: 65s
yarn install: 35s
pnpm install: 18s
bun install: 7s
bun install は Rust の Cargo や Go の module resolver に匹敵する速さを JS エコシステムに持ち込んだ。これは dev 経験の本物の差 だ —— CI で bun install が毎回 5~10 秒で終わり、ローカルで lockfile が変わったときに再インストールが人間の忍耐を試さない。
lockfile 戦争の短い歴史
1.0 が出たとき、bun.lockb は バイナリ lockfile だった。高速なパースを狙ったが、PR レビューで diff が見えないという大きな問題があった。2024~2025 年にコミュニティが強く反発し、Bun は最終的に bun.lock (テキストの JSON-superset 形式) を導入した。2026 年現在、新規プロジェクトはテキスト lockfile がデフォルト。古いプロジェクトは bun.lockb のままのものもある。
教訓: DX の賭けで片側 (速度) のためにもう片側 (diff 可能性、コードレビュー) を無視すると、コミュニティに突き返される。 Bun チームはこれを認めて素早く修正した。それは評価できる。
実際にどこで使われるか
bun install は ランタイムを Bun に変えなくても 導入できる。CI で bun install の後に npm run build や node server.js を走らせる構成は非常によく見る。
- Vercel や Netlify は
bun installをビルド段階のオプションとして提供。 - Next.js、SvelteKit、Astro などの主要フレームワークは Bun で deps を入れても正常にビルド。
- Docker イメージで
oven/bunベースをビルド用に、Node を runtime に組み合わせて、ビルド時間半分。
最も安全な Bun の first step —— そして最も普及している導入 —— が bun install だ。
3 章 · bun test —— 速いが採用は mixed
約束
bun test は Jest 互換 (またはそれに近い) API を掲げ、Jest よりはるかに速く、設定なしで TypeScript を直接実行する。
現実
ベンチマーク上、Bun test は Jest より 310 倍速い。Vitest との差は 13 倍程度 (Vitest が速いときも Bun が速いときもある、スイートの形による)。しかし 採用率 は mixed だ。
| ツール | 2026 中盤の採用感 | 強み |
|---|---|---|
| Jest | いまだに 1 位 (legacy の重み) | エコシステム、プラグイン、安定性 |
| Vitest | 急速に 2 位を追い越し中 | Vite 統合、ESM-native、watch UX |
| Bun test | 3 位、新規プロジェクトでよく見る | 速度、ゼロ設定 TS |
Node test (node:test) | 徐々に増加 | 依存ゼロ、official |
Bun test が メインの座を取れなかった理由 はいくつかある。
- Jest のプラグイン/エコシステム: snapshot serializer、custom matcher、jest-axe、jest-extended など多数のプラグイン。Bun test に全部移植されるには時間がかかった。
- mock システムの差:
jest.mock()互換は徐々に良くなっているが、edge case で違う。 - monorepo 統合: Turborepo や Nx などの monorepo ツールの Jest/Vitest 統合のほうがなめらか。
Bun test は 新規の単一パッケージプロジェクト で最もよく使われる。大規模 monorepo ではいまだに Vitest 優勢。
4 章 · Bun bundler —— esbuild の席に挑んだが
約束
Bun には組み込みのバンドラー bun build がある。esbuild に着想を得たと公言し、より速いと広告。
現実 —— 2026 年のバンドラー風景
2026 年の JS バンドラー風景は 1.0 時点よりずっと混雑している。
| バンドラー | 立ち位置 | 特徴 |
|---|---|---|
| esbuild | いまだに dominant | 最小の表面積、最も安定 |
| Vite (Rollup) | dev server の標準 | HMR、プラグイン生態系 |
| Rolldown | Vite の次世代 | Rust ベース、esbuild より速い可能性 |
| Turbopack | Next.js のデフォルト | Vercel の賭け、Webpack 後継 |
| Bun bundler | niche、主に Bun 生態系内 | 速度、ゼロ設定 TS、Bun ランタイム統合 |
| swcpack | swc のバンドラー分岐 | Vercel 側の前世代 |
Bun bundler は 確かに速い。 しかし プラグインの生態系 が esbuild や Rollup よりはるかに小さい。PostCSS、SVGR、MDX のような領域で esbuild プラグインがそのまま使えない場合が多い (Bun は esbuild のプラグイン API への互換を目指してはいる)。
Bun bundler は Bun 生態系内のデフォルトとしては合理的だ。 Bun.serve で作る小さな SPA、Bun 専用 CLI ツールの dist。しかし esbuild を業界横断で置き換えるところまでは行かなかった。 その座は Rolldown が狙っている。
5 章 · Bun.serve() —— ウェブフレームワークの席を巡る戦い
約束
Bun.serve は「express なしで速い HTTP サーバーを書ける」という約束。Fastify 級のスループットを標準ライブラリから。
コード —— 30 秒で見る Bun.serve
// server.ts
import { serve } from "bun";
serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/hello") {
return new Response("hi");
}
if (url.pathname === "/echo" && req.method === "POST") {
const body = await req.json();
return Response.json({ ok: true, body });
}
return new Response("not found", { status: 404 });
},
});
console.log("listening on http://localhost:3000");
Web 標準の Request/Response API を使うのが要。Cloudflare Workers や Deno と同じパラダイム —— Bun はそこに自分を並べた。
現実 —— Hono の台頭
Bun.serve は速い。しかしその上にルーター、ミドルウェア、バリデーションを載せて初めて本物のアプリになる。2026 年の事実上の標準は Hono だ。
// hono on bun
import { Hono } from "hono";
const app = new Hono();
app.get("/hello", (c) => c.text("hi"));
app.post("/users", async (c) => {
const body = await c.req.json();
return c.json({ id: 1, ...body });
});
export default { fetch: app.fetch, port: 3000 };
Hono は Bun、Deno、Cloudflare Workers、Vercel Edge、Node すべてで同じコードが動く。つまり Hono を選べば ランタイムの選択を後回しにできるし、後から変えられる。 これが大きな売り。Bun.serve に直接結合するコードより、Hono+Bun の組み合わせの方が運用的に安全だ。
Bun.serve は良い。しかしその上で実際にビルドするとき、人々は Hono を選ぶことが多い。 Bun はそれを否定しない —— Bun 公式ドキュメントも Bun.serve 上の推奨ルーターとして Hono を指している。
6 章 · bun:sqlite —— 最も over-deliver した機能
すべての機能のうち、期待以上に良かった ものを一つだけ挙げるなら bun:sqlite だ。
なぜ良いか
Node で SQLite を使うには better-sqlite3 (native addon) または sqlite3 (async) を入れる。どちらもインストール段階で native build を経て、プラットフォーム間の互換問題がときどき出る。bun:sqlite は ランタイムが SQLite を直接持っている —— インストール時のビルドなし、import するだけ。
コード
// sqlite.ts
import { Database } from "bun:sqlite";
const db = new Database("app.db");
db.run(`
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
created_at INTEGER NOT NULL
)
`);
const insert = db.prepare(
"INSERT INTO posts (title, created_at) VALUES (?, ?)"
);
const tx = db.transaction((rows: { title: string; ts: number }[]) => {
for (const r of rows) insert.run(r.title, r.ts);
});
tx([
{ title: "first", ts: Date.now() },
{ title: "second", ts: Date.now() },
]);
const recent = db
.query("SELECT id, title FROM posts ORDER BY id DESC LIMIT 10")
.all() as { id: number; title: string }[];
console.log(recent);
prepared statement、transaction、named parameter —— すべて同期 API。Bun と SQLite が同じプロセスにいるので FFI のオーバーヘッドがない。
使われる場所
- ローカルデータキャッシュ —— CLI ツールのメタデータ保存、小さなサービスの一時ストレージ。
- embedded analytics —— 小さなボードディスプレイ、ミニ BI。
- テスト DB —— Postgres の代わりに in-memory SQLite で統合テスト。
- エージェントのメモリ —— AI エージェントが自分のコンテキスト/メモリを SQLite に保存するパターンが普通。
bun:sqliteは Bun を「次世代の scripting 環境」にする。Python のsqlite3標準ライブラリの席を JS エコシステムに持ち込んだ。
7 章 · Bun shell ($) —— もう一つの上振れ
約束
zx (Google の JS シェルツール) に着想を得た、型安全なシェル。違いは zx が Node 上のサードパーティとして動くのに対し、Bun shell は ランタイム組み込み であること。
コード —— pipeline 例
// shell.ts
import { $ } from "bun";
const files = await $`ls -1 src`.text();
console.log(files);
// パイプとリダイレクト
const wc = await $`cat package.json | wc -l`.text();
console.log("lines in package.json:", wc.trim());
// 安全な変数補間 (shell injection 安全)
const target = "components";
await $`mkdir -p dist/${target}`;
// 失敗時に throw
try {
await $`exit 1`;
} catch (e) {
console.log("caught exit code:", e.exitCode);
}
// 環境変数
const home = (await $`echo $HOME`.text()).trim();
console.log("home:", home);
要点は二つ。
- shell injection 安全性 ——
${target}のような JS interpolation は自動でエスケープされる。os.system(...)系の悪い書き方が型の段階で防がれる。 - TypeScript 統合 —— IDE が補完と型情報を出す。
現実 —— 誰が使うか
Bun shell は ビルドスクリプト、dev tool の事実上の標準の座へ急速に上がってきた。昔 package.json の "scripts" に長く書いていたコマンドが scripts/build.ts に移り、Bun shell で書かれる。
- make の席 の一部を取った。
- シェルスクリプトの可読性問題 (quoting hell、特殊文字エスケープ) を解決。
- cross-platform —— Bun shell は Windows でも同じコードで動く (POSIX エミュレーション)。
Bun shell は Bun を使わない人にも Bun を入れさせる機能 だ。シェルスクリプトが長く脆くなったとき、
bun + $が登場する。
8 章 · bunfig.toml、実行ファイルバンドル、その他
bunfig.toml
Bun の設定ファイル。registry、install behavior、test runner オプション、JSX 変換オプションなどを一ファイルに。
# bunfig.toml
[install]
registry = "https://registry.npmjs.org/"
production = false
[install.cache]
dir = "~/.bun/install/cache"
[test]
preload = ["./test/setup.ts"]
[run]
silent = false
[loader]
".ts" = "tsx"
package.json の一部 (scripts、deps) を侵さず、Bun 固有の設定だけまとめる。良い分離。
実行ファイルバンドル —— bun build --compile
bun build --compile --target=bun-linux-x64 ./cli.ts --outfile mycli
JavaScript コードを 単一実行ファイル にパッケージする。Bun ランタイムが中に同梱される。出力ファイルは 70MB 前後だが、依存なしで実行可能。
比較対象:
- Node 22:
node --experimental-sea-config(Single Executable Application) —— 似た機能、もっと manual。 - Deno 2:
deno compile—— 安定した同等機能。 - pkg (Vercel): legacy ツール、もう活発ではない。
bun --compile は 速い起動 (Bun の cold start advantage が効く) と 依存ゼロ配布 を一度に与える。CLI 作者がよく使う。
その他
- Bun watch (
bun --watch) —— Node の--watchと同等、より速い再起動。 - Bun macros —— ビルド時に JS を実行して結果をインライン化。静的データのベイク。
- Bun lockfile auditing —— セキュリティアドバイザリ統合。
9 章 · Node 22+ のカウンターパンチ —— Bun が投げたボールを Node が受け止めた
Bun の最大の貢献の一つは Node の進化を加速したこと だ。1.0 時点で「古い、遅い、重い」イメージだった Node が、2026 年には本当に速くて modern になった。改善の一部は Bun が突いた弱点を直接ふさいだものだ。
| Bun が誇っていたこと | Node の答え |
|---|---|
| ゼロ設定 TS | node --experimental-strip-types (Node 22) → Node 24 で stable。.ts を直接実行。 |
| 組み込み test runner | node:test モジュール + node --test。2024 年以降 stable、mock 対応も。 |
| native fetch | Node 18 から stable。もう node-fetch を入れる必要なし。 |
| watch モード | node --watch。nodemon 不要。 |
| 環境変数ファイル | node --env-file .env。dotenv 不要。 |
| Single executable app | node --experimental-sea-config。 |
| コアモジュール import | node:fs、node:path プレフィックス。 |
Bun の最大の影響は「Bun を入れさせたこと」ではなく、「Node を刺激して Node が良くなったこと」だ。 すべての JS 開発者がその恩恵を受けている、Bun を使う使わないに関わらず。
Node 22+ のコールドスタートはいまだに Bun より遅く、install 速度は npm のままで遅いままだが、dev 経験の差は劇的に縮まった。
10 章 · Deno 2 との比較 —— Node 互換モードを解放した別の選択肢
Deno も 2024 年に Deno 2 を出して大きな方向転換をした。Node 互換モードを積極的に有効化 し、package.json をネイティブにサポートし、npm モジュールを import 可能にした。
2026 年時点で Bun vs Deno 2 を単純化すると:
| 軸 | Bun | Deno 2 |
|---|---|---|
| ランタイム速度 | 最速 | Bun よりわずかに遅いが十分 |
| Node 互換 | 広いが一部で弱い | Deno 2 で大きく改善、安定 |
| 権限モデル | Node と同じ「全権限」 | デフォルト deny —— 明示的 permission flag |
| 標準ライブラリ | 比較的小さい | 充実、よく整理された (@std) |
| TS サポート | ゼロ設定、速い | ゼロ設定、type check も行う |
| セキュリティ姿勢 | 速度優先 | 安全優先 (サンドボックス) |
| パッケージマネージャー | bun install | deno install (jsr.io または npm:) |
Deno 2 は security 優先、Bun は 速度優先 の姿勢。しかし実利用では両者がますます近づいている —— Node 互換は両側でできる。Deno の --allow-net、--allow-read などの権限 flag は本番セキュリティで差になるが、dev 経験では摩擦を加える。
運用環境が 高セキュリティ prod (政府システム、金融) なら Deno 2 が有利。開発ツール/CI/一般ウェブサービス なら Bun が dev 経験で優勢。会社全体の標準ランタイム ならいまだに Node がデフォルト。
11 章 · Broken promises —— 約束を守れなかった領域
この記事の核心。どこで Bun が約束を守れなかったか。
11.1 「Node を drop-in 置き換え」の narrative
広告コピーはそう始まった。しかし実際には legacy enterprise コードベース で native addon、APM agent、custom debugger、複雑な cluster 利用などで Bun が動かないケースが時々ある。「drop-in」が可能なのは小さなコードベースだ。
11.2 Windows サポート
1.0 時点で最大の broken promise だった。最初の 1 年は Linux/macOS のみ本格対応で、Windows は WSL 推奨。2024 年後半から native Windows サポートが追加されたが、2026 年中盤でも一部モジュールは Windows で edge case がある。
11.3 安定性 (1.0 直後の時期)
1.0 GA 直後の半年は本番で「謎のメモリリーク」「OOM kill」「race condition」などの報告が少なくなかった。会社単位で運用していたところが Node に戻った事例もある。2025 年に入って安定性は大きく改善したが、最初の GA の衝撃は評判に永続的な痕跡を残した。
11.4 観測性と APM のギャップ
Bun の弱点: APM エージェントの instrumentation。New Relic、Datadog、Dynatrace などのメジャー APM が Node 向けに積み上げてきた deep instrumentation を Bun でそのまま受けられるまで 2 年以上かかった。これが運用チームが Bun を採用できない大きな理由 —— 「見えない本番は本番ではない」。
11.5 たまに壊れる Node API
fs.readFile の callback シグネチャ、process.binding の内部依存、worker_threads の一部 edge case —— 狭まってはいるがゼロにはなっていない差。大きなライブラリ (TypeScript コンパイラの一部 path など) が Bun だけわずかに違う挙動になる場合がある。
12 章 · Over-delivered —— 約束以上だった領域
バランスのため、Bun が 期待以上にやった ことも整理する。
12.1 Bun shell
上で触れた。9 章のとおり、Bun shell は 自分の約束を超えて業界デフォルトの道具になった。
12.2 bun install の速度と安定性
最初に広告された 25 倍は計測シナリオによって違ったが、一貫して速い install は約束をよく守った。cold cache、hot cache、lockfile diff —— すべて妥当な速度。
12.3 bun:sqlite
6 章。約束になかった機能だが結果として hit。
12.4 コールドスタート
Lambda や Cloudflare Workers のような serverless 環境で Bun の cold start advantage が 運用上意味のある差 を作った。最初の広告時よりも大きな use case になった。
12.5 Bun チームの応答性
issue が報告されると素早く反応する。lockfile 形式の転換、Windows サポート、Node API 追加 —— コミュニティのフィードバックを真剣に反映した。これは評価できる。
13 章 · 本番で誰が Bun を動かしているか —— 2026 中盤スナップショット
実際に Bun を本番で採用した会社のパターン。
ケース A —— 小さな API ゲートウェイ / エッジ関数
- fly.io 上の小さな Bun.serve インスタンスでルーティング、認証、レート制限だけ処理。
- Cloudflare Workers は自前の V8 isolate を使い Bun ではないが、ローカル dev で Wrangler の代わりに Bun.serve でモックサーバーを立てるパターン が普通。
ケース B —— CLI ツール
- Bun で CLI を作り、
bun build --compileで単一実行ファイル配布。ユーザーは Bun を入れる必要なし。 - Prisma などの一部 CLI コンポーネントが Bun で書かれている。
ケース C —— 社内ツール / dev tool
- 社内ダッシュボード、deploy 自動化、CI helper。Bun.serve +
bun:sqliteで作った小さな運用ツールが非常によくある。
ケース D —— AI エージェントランタイム
- 急増しているパターン: AI エージェントのサンドボックスランタイムとして Bun を使う。速いコールドスタート + bun:sqlite のメモリ + Bun shell のツール実行 の組み合わせが強い。e2b や Modal などの一部 AI infra が Bun runner オプションを提供。
ケース E —— ほぼない —— 大規模モノリス
- 非常に稀。 伝統的な大規模モノリスが Bun に移行したという公開事例は片手で数えられる。リスクに対する見返りが魅力的ではなく、APM/debugger 生態系のプレッシャーが大きい。
明示的に言及される事例 (公開記事ベース)
- Vercel: 自社内部ビルドツールの一部、エッジ関数の一部ワークフローで Bun を採用。
- Mintlify: ドキュメントビルダーの一部。
- Codeium / Replit / Glitch: ユーザーの実行環境の一部選択肢として Bun。
- 多数の スタートアップ: 初期 API の単一インスタンスとして Bun.serve + Hono。
14 章 · 意思決定 —— どこで Bun が合い、どこで Node が合うか
正直な評価。
Bun が合うところ
- CI 速度が重要な dev 作業 ——
bun install+bun testだけで意味のある win。 - CLI ツール ——
bun build --compileで単一ファイル配布、速い起動。 - エッジ/サーバーレス —— コールドスタートの利得。
- scripting / dev tooling —— Bun shell。
- SQLite ヘビーな小さなサービス ——
bun:sqliteの性能。 - 新規プロジェクト、外部依存が少ない —— 互換性問題に当たりにくい。
Node が依然として合うところ
- 大規模 enterprise モノリス —— APM、custom debugger、native addon 生態系が圧倒的。
- legacy コードベースの運用安定性 —— 変更リスクが見返りを上回る。
- deep observability が必須な本番 —— Datadog/NR の auto-instrumentation の完成度。
- 規制が厳しい環境 —— Node の audit / CVE チャネルがよく整備されている。
- 会社の標準ランタイム —— 人を採って教えやすい。
Deno 2 が合うところ
- 高セキュリティ環境 —— permission model が運用上意味のあるところ。
- 標準ライブラリ中心の開発 ——
@stdの安定性。 - 新規プロジェクトだが Node 互換も欲しい —— Deno 2 の npm compat がよくできた。
3 つのランタイムはもう zero-sum ではない。 1 つの会社の中で Bun (dev tooling/CI/CLI)、Node (メインサービス)、Deno (高セキュリティ部分) を併用するケースが増えている。「どれか 1 つが全部勝つ」という narrative は 2026 年にはもう通用しない。
エピローグ —— 約束、請求書、そして次のラウンド
Bun 1.0 GA から 2 年半。まとめると:
Bun は「Node を一気に置き換える」という約束は守れなかった。しかし「JS 生態系を速くする」という約束は (Bun 内部で、そして Node を刺激することで) 守った。 結果としてすべての JS 開発者がより良い道具を使っている —— Bun を採用しているかどうかに関わらず。
覚えておきたい点:
- Bun = ランタイムではなく toolkit として考える人の満足度が高い。
bun install、bun test、Bun shell、bun build --compileを個別に選ぶ。ランタイム採用はゆっくり後で。 - Node 22+ は本当に良くなった。 「古い Node」のイメージなら一度見直そう。
- Deno 2 を忘れるな。 セキュリティ/標準中心の運用に向く選択肢。
- APM 互換はまだ一歩遅い。 本番に行くなら事前確認。
- Windows は徐々に良くなっているが 1 級市民になったのは最近。
採用チェックリスト (Bun 導入の前に)
- うちの APM (NR/DD/Sentry/...) は Bun を公式サポートしているか? どこまで instrumentation 入っているか?
- 依存している native addon (sharp、node-canvas、...) は Bun で動くか?
- うちの CI は Bun をビルド段階で受け入れられるか? Docker base image は?
- うちの人たちは Bun のデバッグに適応する時間があるか? (Chrome DevTools プロトコル互換の限界を理解)
- どこで Bun を導入するか? (段階: lockfile だけ → install だけ → test/scripts → CLI → 小さなサービス → メインサービス)
- rollback シナリオは? Bun→Node の戻りコストは?
よくある anti-pattern
- Node コードをそのまま Bun でデプロイし、非機能要件 (観測性) を忘れる。
- CI 速度の改善が魅力的だからといって本番ランタイムまで一気に変える。 2 つは分離可能で、分離するべき。
- Bun shell を重く使いすぎる —— 一行コマンドはただの
child_process.spawnSyncで十分。 bun:sqliteを本番のプライマリ DB として使う。 SQLite はあくまで単一ノードデータ —— Postgres の席に置くな。- ベンチマークチャートをそのまま信じる。 自分のワークロードで測ろう。「1k qps で速い」と「100k qps で速い」は別問題。
次の記事予告
- 「Hono ガイド 2026 —— runtime-agnostic なウェブフレームワーク (Bun/Deno/Workers/Vercel/Node)」 —— 1 つのコードベースで 5 つのランタイム。
- 「Node 22~24 の進化 —— strip-types、node:test、--watch、--env-file が変えた dev experience」 —— Bun を使わなくても得られる恩恵。
- 「Deno 2 retrospective」 —— Deno 2 の Node 互換の賭けが 1 年後どうなったか。
参考 / References
Bun 公式
- Bun 公式 —— https://bun.sh/ —— 最新バージョン、変更点。
- Bun docs —— https://bun.sh/docs —— ランタイム・バンドラー・テスト・シェルの全体。
- Bun on GitHub —— https://github.com/oven-sh/bun —— issue、release notes。
- Bun blog (releases) —— https://bun.sh/blog —— メジャーバージョンごとの変更。
Node.js
- Node.js 公式 —— https://nodejs.org/
node:testドキュメント —— Node 22+ の native test runner。- Node strip-types 提案 (TC39 type annotations) と TypeScript erasable syntax の関係。
Deno
- Deno 公式 —— https://deno.com/
- Deno 2 announcement —— Node 互換の賭けと
npm:specifier 対応。
ベンチマークと比較
- 「Bun vs Node vs Deno: HTTP performance」 —— 複数のコミュニティベンチマーク (ワークロード依存、自分で測ろう)。
- TechEmpower Web Framework Benchmarks —— Bun/Node/Deno 上のフレームワーク比較の標準出典。
ウェブフレームワーク / runtime-agnostic
- Hono —— https://hono.dev/ —— Bun/Deno/Workers/Node 全部対応。
- itty-router、h3 —— 同カテゴリの別オプション。
SQLite 関連
bun:sqliteドキュメント —— Bun 組み込み SQLite の API。- better-sqlite3 —— Node 側の事実上の標準比較対象。
Bun shell、zx
- Bun shell ドキュメント ——
$API の使い方。 - Google zx —— https://github.com/google/zx —— Bun shell の着想元。
本番採用事例 (公開記事ベース)
- Vercel エンジニアリングブログの Bun 導入記事。
- 多数のスタートアップの回顧 —— 「なぜ Bun を選んだ (選ばなかった) か」系。
批判的視点
- Bun の early-days 本番イシューの回顧。
- APM auto-instrumentation の限界に関する運用チームの記事。
- Node が追いついて差が縮まった領域の分析。
현재 단락 (1/298)
2023 年 9 月、Bun 1.0 が GA で出たときの空気を覚えている。デモは衝撃的だった。`bun install` は `npm install` より 25 倍速く、`bun test` ...