Skip to content
Published on

Bun 回顧 2026 — 1.0 GA の約束と現実、ランタイム・バンドラー・パッケージマネージャー・テストランナー・シェルまで(Bun 2 時点での正直な評価)

Authors

プロローグ —— 2023 年の約束、2026 年の請求書

2023 年 9 月、Bun 1.0 が GA で出たときの空気を覚えている。デモは衝撃的だった。bun installnpm 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 installbun test、Bun shell。CI 時間が半分になる。
  • runtime としての Bun はまだ niche —— Bun.serve で作った小さな API ゲートウェイ、エッジワーカー、社内ツール。大規模モノリスが Bun に移ったという話はほぼ聞かない。
  • Node 22+ が意外と良い守備をした —— node --experimental-strip-typesnode:testnode --watch、native fetch。Node は Bun が投げたボールを自陣で受け止めた。

この記事は 1.0 GA から 2 年半の 正直な回顧 だ。何が over-deliver し、何が broken promise で、どこで Bun が正しく、どこで Node がいまだに正しいのか。


1 章 · Bun ランタイム —— Zig + JavaScriptCore の最初の賭け

約束

Bun は最初から 3 つの賭け をした。

  1. Zig で書き直す —— V8 と Node 自身の C++ グルーの上に立つ Node とは違い、ランタイム自体を Zig で書いて起動時間とメモリフットプリントを小さくする。
  2. V8 ではなく JavaScriptCore (JSC) —— Safari が使うエンジン。起動とメモリで V8 より軽いというのが一般的な評価。
  3. Node API 互換 —— fshttppathcrypto などの 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 年中盤の体感はこうだ。

領域互換ステータス使えるか
fspathosutilほぼ完全はい
httphttpsurlほぼ完全はい
cryptoほぼ OK、一部 legacy API で差はい
child_processほぼ OKはい
worker_threadsOKはい
cluster部分、edge case で差注意
Native addons (N-API)広く対応、一部未対応はい (おおむね)
vm モジュール一部オプション欠落注意
inspector (debugger プロトコル)部分対応注意
async_hooks部分 —— APM ツール互換に影響注意
process.binding 内部 API未サポート (意図的)いいえ

小さなサービスではほぼ問題ない。しかし APM (Application Performance Monitoring) エージェントOpenTelemetry の auto-instrumentationlegacy native addon ではいまだに壊れる。New Relic や Datadog などの主要 APM が公式に Bun をサポートしたのは 2025 年末で、一部の instrumentation はいまだに部分対応のままだ。

「Node コードがそのまま動く」は小さなコードベースでは真、大きなコードベースでは半分真。 壊れるのはビジネスコードではなく 周辺インフラ (tracing、profiler、debugger) の側だ。


2 章 · bun install —— 最も明確な win

すべての領域の中で 最も議論の余地が少ない winbun 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 buildnode server.js を走らせる構成は非常によく見る。

  • Vercel や Netlifybun install をビルド段階のオプションとして提供。
  • Next.js、SvelteKit、Astro などの主要フレームワークは Bun で deps を入れても正常にビルド。
  • Docker イメージoven/bun ベースをビルド用に、Node を runtime に組み合わせて、ビルド時間半分。

最も安全な Bun の first step —— そして最も普及している導入 —— が bun install だ。


3 章 · bun test —— 速いが採用は mixed

約束

bun testJest 互換 (またはそれに近い) API を掲げ、Jest よりはるかに速く、設定なしで TypeScript を直接実行する。

現実

ベンチマーク上、Bun test は Jest より 310 倍速い。Vitest との差は 13 倍程度 (Vitest が速いときも Bun が速いときもある、スイートの形による)。しかし 採用率 は mixed だ。

ツール2026 中盤の採用感強み
Jestいまだに 1 位 (legacy の重み)エコシステム、プラグイン、安定性
Vitest急速に 2 位を追い越し中Vite 統合、ESM-native、watch UX
Bun test3 位、新規プロジェクトでよく見る速度、ゼロ設定 TS
Node test (node:test)徐々に増加依存ゼロ、official

Bun test が メインの座を取れなかった理由 はいくつかある。

  1. Jest のプラグイン/エコシステム: snapshot serializer、custom matcher、jest-axe、jest-extended など多数のプラグイン。Bun test に全部移植されるには時間がかかった。
  2. mock システムの差: jest.mock() 互換は徐々に良くなっているが、edge case で違う。
  3. 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、プラグイン生態系
RolldownVite の次世代Rust ベース、esbuild より速い可能性
TurbopackNext.js のデフォルトVercel の賭け、Webpack 後継
Bun bundlerniche、主に Bun 生態系内速度、ゼロ設定 TS、Bun ランタイム統合
swcpackswc のバンドラー分岐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);

要点は二つ。

  1. shell injection 安全性 —— ${target} のような JS interpolation は自動でエスケープされる。os.system(...) 系の悪い書き方が型の段階で防がれる。
  2. 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 の答え
ゼロ設定 TSnode --experimental-strip-types (Node 22) → Node 24 で stable。.ts を直接実行。
組み込み test runnernode:test モジュール + node --test。2024 年以降 stable、mock 対応も。
native fetchNode 18 から stable。もう node-fetch を入れる必要なし。
watch モードnode --watch。nodemon 不要。
環境変数ファイルnode --env-file .env。dotenv 不要。
Single executable appnode --experimental-sea-config
コアモジュール importnode:fsnode: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 を単純化すると:

BunDeno 2
ランタイム速度最速Bun よりわずかに遅いが十分
Node 互換広いが一部で弱いDeno 2 で大きく改善、安定
権限モデルNode と同じ「全権限」デフォルト deny —— 明示的 permission flag
標準ライブラリ比較的小さい充実、よく整理された (@std)
TS サポートゼロ設定、速いゼロ設定、type check も行う
セキュリティ姿勢速度優先安全優先 (サンドボックス)
パッケージマネージャーbun installdeno 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 が合うところ

  1. CI 速度が重要な dev 作業 —— bun install + bun test だけで意味のある win。
  2. CLI ツール —— bun build --compile で単一ファイル配布、速い起動。
  3. エッジ/サーバーレス —— コールドスタートの利得。
  4. scripting / dev tooling —— Bun shell。
  5. SQLite ヘビーな小さなサービス —— bun:sqlite の性能。
  6. 新規プロジェクト、外部依存が少ない —— 互換性問題に当たりにくい。

Node が依然として合うところ

  1. 大規模 enterprise モノリス —— APM、custom debugger、native addon 生態系が圧倒的。
  2. legacy コードベースの運用安定性 —— 変更リスクが見返りを上回る。
  3. deep observability が必須な本番 —— Datadog/NR の auto-instrumentation の完成度。
  4. 規制が厳しい環境 —— Node の audit / CVE チャネルがよく整備されている。
  5. 会社の標準ランタイム —— 人を採って教えやすい。

Deno 2 が合うところ

  1. 高セキュリティ環境 —— permission model が運用上意味のあるところ。
  2. 標準ライブラリ中心の開発 —— @std の安定性。
  3. 新規プロジェクトだが 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 installbun 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 公式

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

本番採用事例 (公開記事ベース)

  • Vercel エンジニアリングブログの Bun 導入記事。
  • 多数のスタートアップの回顧 —— 「なぜ Bun を選んだ (選ばなかった) か」系。

批判的視点

  • Bun の early-days 本番イシューの回顧。
  • APM auto-instrumentation の限界に関する運用チームの記事。
  • Node が追いついて差が縮まった領域の分析。