Bunとは
Bunは、最近注目を集めている次世代のJavaScriptランタイムです。Node.jsやDenoと同様にサーバーサイドのJavaScript実行環境を提供しますが、高速な起動や統合ツール群(バンドラー、トランスパイラー、パッケージマネージャ)が特徴です。BunのコアはZig という言語で実装されており、パフォーマンス面での優位性を発揮しています。
Bunのここがすごい!
高速性
Node.jsと比較して、サーバの起動時間やリクエスト処理速度が数倍高速です。
統合ツール群
Node.js単体ではランタイムのみを提供し、パッケージ管理(npmやYarn)、バンドラー(webpack、Rollupなど)、トランスパイラー(Babelなど)は別途導入する必要がありますが、BunはそれらすべてBunの中にまとまって提供されます。
TypeScript対応
最新のECMAScript機能をサポートしており、TypeScriptもネイティブに扱えます。TypeScriptをトランスパイルなしで直接実行可能なのでNode.jsではts-node
などを追加でインストールする必要がありますが、Bunならその手間が不要です。
ホットリロード対応
`bun dev
` コマンドを使って立ち上げた開発サーバに、コードの変更をリアルタイムで反映できます。
テストランナー実装
Node.jsを使用する場合はJestのような外部のテストフレームワークを使ってテストしますが、Bun独自のテストランナーを備えているため高速かつシンプルにテストの実行が可能
用語解説
ランタイム
ランタイムとは、プログラムが「実行」される環境のことです。
たとえば、JavaScriptのランタイムとしては、ブラウザ環境が挙げられますが、サーバサイドではNode.jsやBunなどがこれに該当します。これらは、JavaScriptコードを実行するために、独自のAPIやシステムリソース管理の仕組みを備えています。
バンドラー
バンドラーとは、複数のJavaScriptモジュールやその他のリソース(CSS、画像など)を解析し、1つまたは少数のファイルにまとめるツールのことです。
トランスパイル
ソースコードを解析し、構文や機能を理解した上で、目的の環境に適したコードに再生成することです。例えば、型付けされたTypeScriptコードを、ブラウザやNode.jsで実行可能なJavaScriptに変換すること。
前準備
Bun と Node.js の比較をするために、まずは Docker で Bun と Node.js のコンテナを作成していきます。
Bun の Dockerfile
FROM oven/bun:latest WORKDIR /app COPY package.json . COPY server.ts . RUN bun install EXPOSE 3001 CMD ["bun", "run", "server.ts"]
Node.js の Dockerfile
FROM node:18-alpine WORKDIR /app COPY package*.json ./ COPY tsconfig.json ./ COPY server.ts ./ RUN npm install EXPOSE 3002 CMD ["npm", "start"]
docker-compose.yml
version: "3" services: bun-server: build: context: ./bun-server dockerfile: Dockerfile ports: - "3001:3001" container_name: bun-server node-server: build: context: ./node-server dockerfile: Dockerfile ports: - "3002:3002" container_name: node-server
Bun で HTTP サーバーを作成
では早速 Bun を使用して HTTP サーバーを立てていきましょう。
// server.ts import { Server } from "bun"; const server: Server = Bun.serve({ port: 3001, fetch(request: Request): Response { return new Response("Hello from Bun Server!"); }, }); console.log(`Bun server listening on ${server.url}`);
非常にシンプルな記述で HTTP サーバーを立てることができました。
Node.js で HTTP サーバーを立ててみる
では次は Node.js を使用して HTTP サーバーを立てていきましょう。
// server.ts import { createServer, IncomingMessage, ServerResponse } from "http"; const server = createServer((req: IncomingMessage, res: ServerResponse) => { res.statusCode = 200; res.setHeader("Content-Type", "text/plain"); res.end("Hello from Node.js Server!"); }); const PORT: number = 3002; server.listen(PORT, () => { console.log(`Node.js server listening on port ${PORT}`); });
Bun と Node.js のパフォーマンス比較
コンテナの立ち上げ
まずは上記のコードをもとにコンテナを立てて HTTP サーバーを立ててみましょう。
docker-compose up -d
ブラウザで`http://localhost:3001`と`http://localhost:3002`にアクセスして以下のように各サーバーが立ち上がったら成功です。
↓Bunサーバー

↓Node.jsサーバー

ベンチマークテストツール
今回ベンチマークテストツールとして`autocannon`を使用します。
`autocannon`は Node.js の HTTP サーバーのパフォーマンスを計測するためのツールです。(Bun にも使えます)
npm install -g autocannon
Bun サーバーと Node.js サーバーのベンチマークテストを実行してみましょう。
ベンチマークテスト
Bun サーバーと Node.js サーバーのベンチマークテストを実行してみましょう。
autocannon -c 100 -d 30 http://localhost:3001
autocannon -c 100 -d 30 http://localhost:3002
これは各対象の HTTP サーバーに 100 個の同時接続して 30 秒間リクエストを送信してパフォーマンスを計測するコマンドです。
結果を見てみましょう。
PS C:\project\Bun> autocannon -c 100 -d 30 localhost:3001 Running 30s test @ http://localhost:3001 100 connections ┌─────────┬──────┬───────┬───────┬───────┬──────────┬─────────┬────────┐ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │ ├─────────┼──────┼───────┼───────┼───────┼──────────┼─────────┼────────┤ │ Latency │ 8 ms │ 11 ms │ 17 ms │ 19 ms │ 11.76 ms │ 4.18 ms │ 251 ms │ └─────────┴──────┴───────┴───────┴───────┴──────────┴─────────┴────────┘ ┌───────────┬────────┬────────┬─────────┬─────────┬─────────┬─────────┬────────┐ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │ ├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼────────┤ │ Req/Sec │ 5,431 │ 5,431 │ 8,191 │ 9,095 │ 8,201.8 │ 659.22 │ 5,431 │ ├───────────┼────────┼────────┼─────────┼─────────┼─────────┼─────────┼────────┤ │ Bytes/Sec │ 750 kB │ 750 kB │ 1.13 MB │ 1.25 MB │ 1.13 MB │ 90.9 kB │ 749 kB │ └───────────┴────────┴────────┴─────────┴─────────┴─────────┴─────────┴────────┘ Req/Bytes counts sampled once per second. # of samples: 30 246k requests in 30.23s, 34 MB read PS C:\project\Bun> PS C:\project\Bun> PS C:\project\Bun> autocannon -c 100 -d 30 localhost:3002 Running 30s test @ http://localhost:3002 100 connections ┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │ ├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤ │ Latency │ 11 ms │ 15 ms │ 30 ms │ 33 ms │ 15.95 ms │ 5.47 ms │ 158 ms │ └─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘ ┌───────────┬────────┬────────┬─────────┬────────┬──────────┬────────┬────────┐ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │ ├───────────┼────────┼────────┼─────────┼────────┼──────────┼────────┼────────┤ │ Req/Sec │ 3,553 │ 3,553 │ 6,235 │ 6,847 │ 6,080.77 │ 577.53 │ 3,552 │ ├───────────┼────────┼────────┼─────────┼────────┼──────────┼────────┼────────┤ │ Bytes/Sec │ 622 kB │ 622 kB │ 1.09 MB │ 1.2 MB │ 1.06 MB │ 101 kB │ 622 kB │ └───────────┴────────┴────────┴─────────┴────────┴──────────┴────────┴────────┘ Req/Bytes counts sampled once per second. # of samples: 30 183k requests in 30.06s, 31.9 MB read
こちら上記結果をChatGPTくんに要約してもらったものです。
レイテンシー(応答時間): 3001(Bun): 平均11.76ms 3002(Node.js): 平均15.95ms → 3001の方が約35%速い 毎秒リクエスト処理数(Req/Sec): 3001(Bun): 平均8,201.8 3002(Node.js): 平均6,080.77 → 3001の方が約35%多くのリクエストを処理 30秒間の総リクエスト数: 3001(Bun): 246,000リクエスト 3002(Node.js): 183,000リクエスト → 3001の方が約63,000リクエスト多く処理
こんな単純な処理を返すサーバーでもBunの方がNode.jsよりも高いパフォーマンスを発揮していることがわかりますね。
まとめ
BunはNode.jsよりも高速で、シンプルな記述でHTTPサーバーを立てることができます。
皆さんもぜひBunを使ってみてください。