Bun:JavaScript ランタイム、パッケージ管理、テスト、バンドルを一つにまとめる

Bun は oven-sh によるオープンソースの JavaScript / TypeScript 統合ツールチェーンです。ランタイム、パッケージマネージャー、スクリプト実行、テストランナー、バンドラーを一つの bun コマンドにまとめ、Node.js エコシステムとの互換性を保ちながら起動、インストール、開発体験を改善することを目指しています。

Bun は oven-sh が開発する JavaScript / TypeScript の統合ツールチェーンです。

単に速い Node.js 代替を目指しているだけではありません。ランタイム、パッケージマネージャー、スクリプト実行、テストランナー、バンドラーを同じ bun コマンドにまとめます。フロントエンドや Node.js 開発者にとっての魅力は、ツールを減らし、インストールやビルドの待ち時間を減らし、多くの作業を一つのコマンドで済ませられることです。

プロジェクト:https://github.com/oven-sh/bun

まず結論

Bun は JavaScript ツールチェーンを簡素化したい人に向いています。

できることは次の通りです。

  • JavaScript、TypeScript、JSX、TSX を実行する。
  • Node.js 互換ランタイムとして使う。
  • npm / yarn / pnpm の代わりにパッケージ管理を行う。
  • package.json の scripts を実行する。
  • テストを実行する。
  • フロントエンドまたはバックエンドのコードをバンドルする。
  • bunx で npm パッケージ内のコマンドを実行する。
  • Bun.servebun:sqliteBun.sqlBun.redisBun.s3 などの組み込み API を提供する。

最大の価値は開発体験です。依存関係のインストールが速く、起動も速く、コマンドが統一され、TypeScript と JSX がそのまま使えます。

ただし、すべてのプロジェクトがすぐに Bun へ切り替えるべきではありません。大規模 Node.js プロジェクト、ネイティブ拡張に強く依存するプロジェクト、安定性要求が高い本番サービスでは、互換性、ビルド、テスト、デプロイ方式を一つずつ検証する必要があります。

Bun とは

公式 README によると、Bun は JavaScript と TypeScript アプリケーション向けの統合ツールキットです。単一の実行ファイル bun として配布されます。

中心は Bun runtime です。これは Node.js の drop-in replacement を目指す高速 JavaScript ランタイムです。Bun は Zig で書かれ、JavaScriptCore をベースにし、起動時間とメモリ使用量を重視して最適化されています。

つまり、次のように直接実行できます。

1
bun run index.tsx

TypeScript と JSX は追加設定なしで動きます。

同じ bun コマンドには、test runner、script runner、Node.js 互換パッケージマネージャー、bundler、package runner も含まれます。

よく使うコマンドは次の通りです。

1
2
3
4
bun test
bun run start
bun install <pkg>
bunx cowsay 'Hello, world!'

従来は nodenpmpnpmtsxjestvitestwebpackesbuildts-node などが同じプロジェクトに並びがちでした。Bun は高頻度の作業を一つのツールにまとめようとしています。

インストール方法

Bun は Linux、macOS、Windows をサポートし、x64 と arm64 に対応しています。

公式の推奨インストールスクリプト:

1
curl -fsSL https://bun.com/install | bash

Windows:

1
powershell -c "irm bun.sh/install.ps1 | iex"

npm からもインストールできます。

1
npm install -g bun

macOS Homebrew:

1
2
brew tap oven-sh/bun
brew install bun

Docker:

1
2
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

Linux ではカーネルバージョンに注意が必要です。README では Linux kernel 5.6 以上を強く推奨し、最低要件は 5.1 とされています。

最新版へ更新:

1
bun upgrade

canary へ更新:

1
bun upgrade --canary

本番環境で canary を直接使うのは通常おすすめしません。新機能の検証や特定バグの切り分け用途に留めるべきです。

なぜ Bun は速いのか

Bun の速さはいくつかの層から来ています。

第一に、ランタイムの起動が速いことです。多くの CLI ツールや開発スクリプトのボトルネックは長時間の CPU 処理ではなく、プロセス起動、モジュール読み込み、TypeScript 変換、依存関係解決です。Bun はこの経路を最適化しています。

第二に、パッケージ管理が速いことです。bun install は npm / yarn / pnpm の依存関係インストールを置き換えることを目指します。グローバルキャッシュと独自の lockfile により、大量の依存関係を扱うときに待ち時間を減らせます。

第三に、TypeScript / JSX がそのまま動くことです。.ts.tsx のスクリプトを実行するだけでも、従来の Node.js では tsxts-node、Babel、ビルド手順が必要になりがちでした。Bun は直接実行でき、接着剤のようなツールを減らします。

第四に、組み込みツールによりプロセスと設定の切り替えが減ります。テスト、スクリプト、バンドル、実行が同じツール内にあります。

ただし、「Bun は速い」は「どのプロジェクトでも必ず速い」という意味ではありません。実際の効果は依存関係、スクリプト、テストフレームワーク、ビルド設定、Node.js API 利用、CI キャッシュに依存します。

パッケージ管理:npm / yarn / pnpm の代替

Bun は依存関係を直接インストールできます。

1
bun install

依存関係を追加:

1
bun add react

開発依存を追加:

1
bun add -d typescript

依存関係を削除:

1
bun remove react

なぜ依存しているかを見る:

1
bun why react

セキュリティチェック:

1
bun audit

npm や pnpm から移行する場合は、bun.lock をコミットするか、CI で bun install --frozen-lockfile を使うか、private registry と .npmrc が互換か、workspace の挙動が期待通りか、lifecycle scripts が安全リスクにならないかを確認します。

小さなプロジェクトなら直接試せます。大規模 monorepo は、一つの package や非ブロッキング CI job から始める方が安全です。

スクリプトと TypeScript の実行

Bun は package.json のスクリプトを実行できます。

1
bun run start

ファイルを直接実行することもできます。

1
2
bun run index.ts
bun run index.tsx

これは scripts/build.tsscripts/seed.tsscripts/migrate.tsscripts/check.ts のようなツールスクリプトに便利です。

Node.js では TypeScript loader や事前コンパイルが必要になりがちですが、Bun なら軽くできます。

ただし、loader、ESM/CJS 境界、ネイティブモジュール、child process、ファイル監視、一部のエッジ API など Node.js 固有の挙動に依存する場合はテストが必要です。

テストランナー

Bun にはテストランナーがあります。

1
bun test

Jest / Vitest の設定を減らしたい小規模プロジェクトや、一部の単体テスト、ツールテスト、ライブラリテストを軽い実行方式へ移す用途に向いています。

移行時は、expect、mock API、snapshot、DOM テスト環境、テスト探索規則、coverage 出力、CI reporter の違いを確認します。

Jest の custom matcher、複雑な mock、jsdom、babel-jest、ts-jest に深く依存している場合は急がない方がよいです。新規モジュールだけ bun test を使い、既存テストは元のフレームワークに残せます。

バンドルとビルド

Bun には bundler もあります。

1
bun build ./src/index.ts --outdir ./dist

フロントエンド、バックエンドスクリプト、CLI、ライブラリのビルドに使えます。Bun のドキュメントは loaders、plugins、macros、CSS、HTML、HMR、minifier、single-file executable も扱います。

優先して試しやすいのは、小さなフロントエンドツール、Node.js CLI、内部スクリプト、単一ファイルサービス、複雑な webpack loader に依存しないプロジェクトです。

慎重に進めるべきなのは、複雑な webpack plugin chain、大量の Vite plugin、深い Babel 変換、特殊な CSS / asset pipeline、micro frontend、module federation、hash や chunk や互換性に厳しいプロジェクトです。

Bun bundler は魅力的ですが、ビルドツール移行のリスクはパッケージ管理より高いことが多いので、単独で検証した方がよいです。

HTTP サービスの実行

Bun は Bun.serve を提供します。

1
2
3
4
5
6
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello from Bun")
  },
})

小さな API、内部サービス、Webhook receiver、エッジ風サービスには便利です。WebSockets、Workers、Streams、SQLite、PostgreSQL、Redis、S3、TCP/UDP sockets などの API もあります。

すでに Express、Fastify、NestJS、Next.js、Hono、Elysia などを使っているなら、まず Bun 上での互換性を確認すれば十分です。Bun を使うためだけにサービスを書き直す必要はありません。

現実的な順序は、開発スクリプトとパッケージ管理、次にテスト、最後に本番ランタイム移行の評価です。本番挙動に直接影響するため、ランタイム移行が最も慎重に扱うべき部分です。

Node.js との関係

Bun の目標の一つは Node.js の drop-in replacement ですが、「互換」は「完全に同一」ではありません。

Node.js エコシステムには、CJS / ESM 相互運用、組み込みモジュール、ネイティブ拡張、npm lifecycle scripts、ファイルシステムの細かな挙動、stream と Buffer、worker / child_process、デバッグや profiling など、多くの細部があります。

Bun の互換性は速く改善していますが、本番移行はテスト結果を基準にすべきです。

確認すべきことは、テストが Bun で通るか、重要な依存関係が Bun をサポートするか、ビルド成果物が一致するか、CI とローカルの挙動が一致するか、本番に監視と rollback があるか、Docker イメージとデプロイスクリプトが安定しているかです。

パッケージマネージャーだけを置き換えるリスクは低めです。本番ランタイムを置き換えるリスクはかなり高くなります。

向いているプロジェクト

Bun は、新しい小規模 JavaScript / TypeScript プロジェクト、内部ツール、CLI、依存関係インストールを速くしたい CI、ツールチェーンを減らしたいフロントエンド、起動速度が重要なスクリプトやサービス、TypeScript をすぐ動かしたい開発者に向いています。

一方で、巨大 monorepo、pnpm workspace の挙動に深く依存するプロジェクト、多数の Node.js ネイティブ拡張を使うサービス、高度にカスタムされたフロントエンドビルド、本番ランタイムの一致性が極めて重要なバックエンド、Jest に深く依存するテストスイートでは慎重に進めるべきです。

保守的ですが実用的な方針は、まず Bun を開発ツールとして使うことです。いきなり全ての本番ランタイムを置き換える必要はありません。

移行のすすめ方

既存プロジェクトで Bun を試すなら、次の順序がよいです。

  1. ローカルに Bun をインストールする。
  2. bun install を実行し、依存関係の結果を見る。
  3. bun.lock をコミットまたは一時保持し、既存 lockfile との混乱を避ける。
  4. よく使うスクリプトを bun run <script> で試す。
  5. 少数のテストを bun test に移す。
  6. CI に非ブロッキングの Bun job を追加する。
  7. 互換性に問題がなければ、主なインストールフローの置き換えを検討する。
  8. 本番ランタイム移行は最後に評価する。

チームプロジェクトでは rollback 経路を残すべきです。旧 npm / pnpm / yarn フローを保持し、CI でしばらく並走させ、ランタイム、パッケージマネージャー、テストフレームワーク、バンドラーを同時に変えないことが大切です。

よく使うコマンド

インストール:

1
curl -fsSL https://bun.com/install | bash

アップグレード:

1
bun upgrade

依存関係のインストール:

1
bun install

依存関係の追加:

1
bun add lodash

スクリプト実行:

1
bun run dev

TypeScript を直接実行:

1
bun run scripts/build.ts

テスト:

1
bun test

バンドル:

1
bun build ./src/index.ts --outdir ./dist

パッケージコマンドを実行:

1
bunx cowsay 'Hello, world!'

まとめ

Bun の価値は「Node.js より速い」だけではありません。JavaScript / TypeScript 開発に散らばるランタイム、パッケージマネージャー、スクリプト実行、テスト、バンドルを一つの bun コマンドへまとめる点が重要です。

新規プロジェクトや内部ツールでは、速いインストール、速い起動、少ない設定、TypeScript / JSX の直接実行が快適です。既存の大規模プロジェクトでは、パッケージインストール、スクリプト、一部テストなど低リスクな部分から入り、ビルドとランタイムを段階的に検証する方が安全です。

Node.js ツールチェーンのインストール速度、設定の断片化、テスト起動時間に悩まされているなら、Bun は試す価値があります。ただし本番移行では、テスト、依存関係、CI、rollback という基本的な工学判断に戻るべきです。

参考リンク:

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。