Bun vs Node.js 2026年 — 速度・互換性・本番採用の実態比較


はじめに

Bun は2023年に正式版をリリースし、JavaScriptランタイム・バンドラー・テストランナー・パッケージマネージャーをオールインワンで提供するツールキットです。「Node.jsの置き換え」として大きな注目を集めていますが、2026年時点での実態はどうでしょうか。

本記事では、速度・互換性・本番採用の観点からBunとNode.jsを徹底比較します。

ベンチマーク比較

HTTP サーバーパフォーマンス

HTTP リクエスト処理 (req/sec) - 2026年ベンチマーク

シンプルなHello World API:
Bun:      ~ 250,000 req/sec
Node.js:  ~ 85,000 req/sec
Deno:     ~ 120,000 req/sec

JSON API (読み取り):
Bun:      ~ 180,000 req/sec
Node.js:  ~ 65,000 req/sec

DB クエリ (PostgreSQL):
Bun:      ~ 45,000 req/sec
Node.js:  ~ 38,000 req/sec

起動時間とファイル操作

操作BunNode.js
スクリプト起動5ms45ms
TypeScript実行12ms要トランスパイル
ファイル読み取り(1MB)2ms8ms
npm install (cold)1.2秒8.5秒

BunのパッケージインストールはNode.js(npm)の約7倍高速です。これはローカル開発のDXを大きく改善します。

Bun の主要機能

TypeScript のネイティブ実行

// tsconfig.json 不要・トランスパイル不要
// bun run app.ts で直接実行できる

import { Hono } from 'hono';

const app = new Hono();

interface User {
  id: number;
  name: string;
  email: string;
}

const users: User[] = [
  { id: 1, name: '田中太郎', email: 'tanaka@example.com' },
  { id: 2, name: '佐藤花子', email: 'sato@example.com' },
];

app.get('/users', (c) => c.json(users));

app.get('/users/:id', (c) => {
  const id = parseInt(c.req.param('id'));
  const user = users.find((u) => u.id === id);
  if (!user) return c.json({ error: 'Not Found' }, 404);
  return c.json(user);
});

Bun.serve({
  fetch: app.fetch,
  port: 3000,
});

console.log('サーバー起動: http://localhost:3000');

組み込みのテストランナー

// app.test.ts
import { describe, test, expect, beforeEach, mock } from 'bun:test';

describe('UserService', () => {
  let userService: UserService;

  beforeEach(() => {
    userService = new UserService();
  });

  test('ユーザーを作成できる', async () => {
    const user = await userService.create({
      name: '田中太郎',
      email: 'tanaka@example.com',
    });

    expect(user.id).toBeDefined();
    expect(user.name).toBe('田中太郎');
  });

  test('メールが重複するとエラーになる', async () => {
    await userService.create({
      name: '田中太郎',
      email: 'tanaka@example.com',
    });

    expect(async () => {
      await userService.create({
        name: '田中次郎',
        email: 'tanaka@example.com', // 重複
      });
    }).toThrow('Email already exists');
  });

  test('モック関数が呼ばれる', () => {
    const mockFn = mock((x: number) => x * 2);
    expect(mockFn(5)).toBe(10);
    expect(mockFn).toHaveBeenCalledWith(5);
    expect(mockFn).toHaveBeenCalledTimes(1);
  });
});

実行は bun test のみ。Jest・Vitestのような追加設定は不要です。

Bun.file — 高速ファイルI/O

// ファイル読み取り
const file = Bun.file('./data.json');
const data = await file.json(); // JSON自動パース

// ファイル書き込み
await Bun.write('./output.json', JSON.stringify(data, null, 2));

// ストリーム処理
const stream = Bun.file('./large-file.csv').stream();
for await (const chunk of stream) {
  // チャンク処理
}

// 環境変数(.envファイル自動読み込み)
const apiKey = process.env.API_KEY; // .envから自動読み込み
// ↑ dotenv不要!

npm 互換性の現状(2026年)

BunはNode.jsとnpmのエコシステムとの互換性を継続的に向上させています。

互換性が高いカテゴリ

  • Webフレームワーク: Express、Hono、Fastify(一部機能制限あり)
  • ORMs: Prisma、Drizzle ORM
  • テストツール: Jest(ほぼ互換)、Vitest
  • ユーティリティ: Lodash、date-fns、zod

注意が必要なカテゴリ

// Node.js固有のAPIへの依存
import { Worker } from 'worker_threads';  // 部分的にサポート
import { createServer } from 'net';       // 基本的にサポート
import { createInterface } from 'readline'; // サポート

// ネイティブアドオン(.node ファイル)
// → 互換性が低い。Node.js API を使用するネイティブバイナリは要確認

// 例: bcryptjs(Pure JS)は動作する
import bcrypt from 'bcryptjs';
const hash = await bcrypt.hash('password', 10); // OK

// node-gyp を使うネイティブビルドのモジュールは要注意

Node.js が優位なケース

Bunの高速性は魅力的ですが、Node.jsを選ぶべきケースもあります。

  1. 大規模なエンタープライズプロジェクト: Node.jsのエコシステムと運用実績
  2. ネイティブアドオンへの依存: 特定のnativeモジュール使用
  3. 既存CI/CDパイプライン: Node.js前提のインフラ構成
  4. AWS Lambda / Cloud Run: BunのDockerイメージはNode.jsより大きい
# Node.js Alpine(最小構成)
FROM node:22-alpine
# イメージサイズ: ~50MB

# Bun(最小構成)
FROM oven/bun:1-alpine
# イメージサイズ: ~90MB(2026年現在、縮小傾向)

移行ガイド(Node.js → Bun)

パッケージマネージャーの移行

# package.json はそのまま使える
# npm install → bun install
bun install

# npm run dev → bun dev  or  bun run dev
bun dev

# npx → bunx
bunx create-next-app@latest my-app

# Node.js バイナリ実行
bun run server.js  # node server.js と同等
bun run server.ts  # TypeScript直接実行

環境変数の扱い

// .env ファイルは自動読み込み(dotenv不要)
// .env.local, .env.development なども対応

// Node.js
require('dotenv').config(); // 必要
const port = process.env.PORT ?? 3000;

// Bun
// dotenv インポート不要
const port = process.env.PORT ?? 3000; // そのまま動く

移行チェックリスト(Node.js → Bun)

段階的にBunへ移行する際は、以下のチェックリストを活用してください。

Phase 1: パッケージマネージャーのみ移行

# 1. bun をインストール
curl -fsSL https://bun.sh/install | bash

# 2. 既存プロジェクトで bun install を実行
bun install  # → bun.lockb が生成される

# 3. スクリプト実行を確認
bun run dev && bun run build && bun run test

Phase 1 チェック項目:

  • bun install / bun run dev / bun run build / bun run test が正常動作
  • CI/CDパイプラインが動作する(oven-sh/setup-bun@v2 を追加)

Phase 2: ランタイム移行

bun run src/index.ts でアプリケーション全体をBunランタイムで実行し、API・DB接続・メモリ使用量を確認します。dotenv・ts-node・node-fetch・nodemonなどBunに組み込まれた機能と重複するパッケージは削除できます。

詳細パフォーマンスベンチマーク

実際のユースケースに近い条件でのベンチマーク結果です。

Webフレームワーク別パフォーマンス

Express (Node.js) vs Hono (Bun) — JSON APIレスポンス

Express + Node.js 22:
  Requests/sec:  42,000
  Latency avg:   2.3ms
  Memory:        85MB

Hono + Bun 1.2:
  Requests/sec:  158,000
  Latency avg:   0.6ms
  Memory:        52MB

※ MacBook Pro M3, wrk -t4 -c100 -d30s

テスト実行速度の比較

プロジェクト規模: 350テスト(ユニット+統合)

Jest + Node.js:     初回 18.2秒 / 再実行 4.5秒
Vitest + Node.js:   初回 8.7秒  / 再実行 1.8秒
bun:test + Bun:     初回 3.1秒  / 再実行 0.8秒

エコシステム互換性の詳細

完全互換(問題なく動作)

カテゴリライブラリ備考
WebフレームワークHono, Express, KoaHonoは特に相性が良い
ORMDrizzle ORM, PrismaPrismaはv5.8以降で安定
バリデーションZod, Valibot完全動作
ユーティリティLodash, date-fns, nanoid完全動作

一部制限あり・非互換

ライブラリ状態対応策
Fastify一部制限プラグインの互換性を個別確認
Socket.io一部制限Bunの組み込みWSを推奨
dotenv不要Bunは.envを自動読み込み
ts-node / tsx不要BunはTS直接実行
nodemon不要bun --watch で代替

まとめ

2026年時点でのBun vs Node.jsの結論です。

観点BunNode.js
実行速度2〜3倍高速安定・実績あり
TypeScriptネイティブ対応要設定
npm互換性約95%100%
エコシステム急成長中成熟・豊富
本番採用増加中主流

新規プロジェクト:ウェブAPI、スクリプト、CLIツールであればBunの採用を強くお勧めします。開発体験が大幅に向上します。

既存プロジェクト:パッケージマネージャーとして bun install だけ採用する「段階的移行」から始めるのが現実的です。

関連記事