1月22日、Node.js互換の高速JavaScriptランタイムBun、新バージョンである1.2をリリースした。(公式のリリースノート)

監修者からのコメント:
本記事は、以下のエキスパートに監修していただきました:
yosuke_furukawa: Bunはリリースが早く、しかも膨大な数の機能を毎回リリースしています。
Bun 1.1は Bun 1.1.45 までバージョンも出てますが、セマンティックバージョニングではなく、全てパッチバージョンで機能を追加しています。ある程度機能がまとまったらマイナーバージョンを上げていく方針なんじゃないかと感じています。
昨今 Deno も 2024年における進化を記述しています。 Deno in 2024 , Techfeed 紹介
どちらも Node の互換性を上げるという方針で、まずはNode.jsのユーザベースを引っ張っていき、自分たちの体験を上げていくようにしています。
Bunはパフォーマンス面で圧倒的な速度を提供しようとしており、その辺りが今までフックとなってユーザが増えていましたが、ここに来て Bun
オブジェクトに色々生やしており、デフォルトで必要なセット全部詰め合わせてくる感じがすごいですね。しかも個別に import するのではなく、 Bun というグローバルオブジェクトに生やすという Good Old なスタイルで対応しています。 Bun.s3 に関しては s3 以外も対応していたり、 sql は postgres のものだけ対応していたりと、独特なセンスがあります。そこに Bun 作者が思うデファクトスタンダードがあるんだと思います。
このあとメンテナンス大変そうな印象を受けますが、ブルドーザーのように思い付きを試しながら駄目になったらやめていくというスタイルで進めていくんだろうと思います。その辺りもBunの魅力だと思います。
1.2での変更点まとめ
Bun 1.2の主な変更点を簡潔にまとめると、以下のようになる。
Node.js 互換性の強化
- Node.js のテストスイートを取り入れ、数多くのバグ修正・機能追加を実施。
- HTTP/2(node:http2)、dgram(UDP)、cluster、zlibなど各モジュール対応が拡充し、多くのAPIがNode.js並みに動作可能になった。
S3 APIのネイティブサポート
- 「Bun.s3」などの組み込み機能を用いて、ファイルのアップロード・ダウンロード、削除、プリサインドURL生成が可能。
- Node.jsのAWS SDKを使うより5倍ほど高速なパフォーマンスを実現。
Postgres対応の新SQLクライアント
- 「Bun.sql」でPostgresを直接操作できるようになり、既存のNode.jsライブラリより最大50%速い性能を目指す。
- SQLクエリをタグ付きテンプレートで書けるため、コードの見通しが良く、安全性(SQLインジェクション対策)も高い。
HTTPサーバのパフォーマンス向上
- ExpressをBun上で動かした際に最大3倍ほど高速になるよう最適化。
その他
- テキストベースのロックファイル「bun.lock」を導入したパッケージ管理(bun install)の改善。
- V8互換APIをJavaScriptCore上で独自にエミュレーションし、一部C++拡張モジュール(cpu-featuresなど)がそのまま動作可能。
以下に、それぞれのトピックについて簡単に紹介する。
Node.js互換性のさらなる向上
Bunは、Bun 1.2で公式Node.jsテストスイートを大幅に取り込み、各種APIの互換性を一段と強化した。特にHTTP/2、dgram、Cluster、Zlibなどのモジュールが充実し、Node.js同様の使い勝手が得られるようになった。これにあわせて、Expressなどのフレームワークも高速に動作するよう最適化されており、 最大で約3倍のパフォーマンス向上 が報告されている。
// HTTP/2サーバの例
import { createSecureServer } from "node:http2";
import { readFileSync } from "node:fs";
const server = createSecureServer({
key: readFileSync("key.pem"),
cert: readFileSync("cert.pem"),
});
server.on("stream", (stream) => {
stream.respond({ ":status": 200, "content-type": "text/plain" });
stream.end("Hello from Bun over HTTP/2!");
});
server.listen(3000, () => {
console.log("HTTP/2 server running on port 3000");
});
S3のネイティブサポート
Bun 1.2では、組み込みのS3クライアント(Bun.s3
)を追加し、オブジェクトストレージへのファイルアップロード・ダウンロード・削除、プリサインドURLの生成などを高パフォーマンスに実行できる。これにより、 AWS SDKより最大5倍高速に動作 するとされる。fetch("s3://...")
のように、S3のオブジェクトを直接操作可能なのも特徴だ。
// S3へのファイルアップロード例
import { s3 } from "bun";
const file = s3.file("folder/my-file.txt");
await file.write("Hello S3 from Bun!");
console.log("Upload completed");
詳細はhttps://bun.sh/docs/api/s3を参照。
Postgres対応の新SQLクライアント(Bun.sql
)
これまでも組み込みのSQLiteクライアントが用意されていたが、Bun 1.2で新たにPostgresにも対応した。Bun.sql
はオートエスケープやプリペアドステートメント化などにより、 Node.jsの既存ライブラリより約50%高速 とされている。使い方はタグ付きテンプレートリテラルに近く、postgres.js
からの移行もしやすい。
// Postgresからデータを取得
import { sql } from "bun";
const name = "Alice";
const rows = await sql`
SELECT age FROM users
WHERE name = ${name}
`;
console.log(rows); // => [{ age: 25 }] など
(関連ドキュメント: https://bun.sh/docs/api/sql)
HTTPサーバの高速化
BunはもともとHTTPサーバ内蔵機能(Bun.serve()
など)を持ち、軽量かつ高速に動作することで知られているが、Bun 1.2ではExpressなどのNode.js向けフレームワークを動かした場合にも最大3倍程度の速度向上が実現されている。
import express from "express";
const app = express();
app.get("/", (req, res) => {
res.send("Hello from Bun + Express!");
});
app.listen(3000, () => {
console.log("Express server running on Bun, port 3000");
});
上記のようにNode.jsで慣れ親しんだコードがほぼそのまま動作しながら、高いパフォーマンスを得られるのが特長だ。
bun.lock(テキストベースのロックファイル)
bun install
コマンドで生成されるロックファイルが、テキスト形式(bun.lock
)に変更となった。これにより以下のメリットがある。
- バージョン管理ツール(Gitなど)で差分を追いやすい
- 手動編集でパッケージのバージョン指定などを柔軟に行いやすい
Node.jsのpackage-lock.json
やYarnのyarn.lock
と似た運用ができるため、プロジェクト管理がよりしやすくなった。
V8互換APIへの対応
BunはJavaScriptCoreをエンジンとしているが、Node.jsのV8 C++アドオンを利用するパッケージの動作をサポートするために、内部でV8 APIをエミュレーションする仕組みを導入している。これにより、
- 一部のC++拡張モジュールが、そのままBun上でもビルドして動かせる
cpu-features
のようにV8 APIを直接呼び出すnpmモジュールにも対応
依然として未サポートの部分は残るが、今後さらに充実していく見込みとのこと。
その他のトピック
以下に、公式のリリースノートから特に興味深いトピックを抜粋してお届けする。
HTMLインポートの追加
フロントエンドのHTML・CSS・JSを一括で扱えるHTMLインポートがBun 1.2でサポートされた。Bun.serve()
のstaticオプションでHTMLファイルを指定すると、HTML内の<script>
や<link>
タグを自動でバンドルし、まとめて配信可能になる。
import homepage from "./index.html";
Bun.serve({
static: {
"/": homepage,
},
async fetch(req) {
// APIリクエストなど
},
});
HTML内の<script>
や<link rel="stylesheet">
をまとめてビルドした上でルートに割り当てるため、フロントエンドのツールチェーンを簡略化できる。より詳しい実装は「HTML imports documentation」を参照。
スタンドアロン実行ファイル(--compileオプション)
bun build --compile
で、Bunランタイムとアプリを1つのバイナリにまとめたスタンドアロン実行ファイルを作成できる。Bun 1.2ではクロスコンパイルもサポートされ、Linux上でWindows用のバイナリをビルドするといったことが可能になった。
bun build --compile --target=bun-windows-x64 app.ts
# Windows用のapp.exeを出力
Windows用アイコンの設定やコンソール非表示も行える。
バイトコードキャッシュ(--bytecodeフラグ)
bun build --bytecode
フラグを使用すると、バイトコードキャッシュを生成でき、アプリケーションの起動がさらに高速化される。eslint
などの起動が2倍ほど速くなる例が報告されている。なお、バイトコードキャッシュは容量が大きいため、ディスク使用量とのトレードオフがある。
# バイトコードキャッシュを生成しつつコンパイル
bun build --bytecode --compile app.ts
CommonJS出力形式のサポート
これまでbun build
はESM出力が基本だったが、Bun 1.2では--format=cjs
オプションを使ってCommonJS形式の出力も可能になった。古いNode.js環境やCommonJSのワークフローとの連携が容易になる。
bun build --format=cjs app.ts
また、CJS/ESM混在のコードや動的require
呼び出しなどの判定精度も向上しており、"use strict"; eval(...)
など特殊なケースでも正しく認識する仕組みが取り入れられた。
プラグインAPIの改善
BunにはプラグインAPIが用意されており、独自のローダーを実装したり、importをフックして挙動を変えたりできる。Bun 1.2ではonBeforeParse()
フックが追加され、C/C++/Rustなどで書いたN-APIアドオンで、コードをパースする直前の最適化や変形を行うことが可能になった。これによりバンドルやビルドの拡張がさらに自由になっている。
// Rust側サンプル断片
#[bun]
pub fn replace_foo_with_bar(handle: &mut OnBeforeParse) -> Result<()> {
let input_source_code = handle.input_source_code()?;
let output_source_code = input_source_code.replace("foo", "bar");
// ...
}
CSSパーサ・バンドラの強化
Bun 1.2のbun build
では、LightningCSSをもとにした独自実装のCSSパーサ・バンドラを追加し、CSSの@importやurl()をまとめて一つのファイルに統合できる。JavaScriptでimport "./style.css";
のようにCSSを読み込むと、その依存関係をすべて束ねたCSSファイルを自動生成してくれるため、フロントエンドの開発を簡素化できる。
# index.tsとCSSファイルを同時にビルド
bun build ./index.ts --outdir=dist
# => index.js, index.css が生成される
まとめ
Bun 1.2では、Node.js互換の充実をはじめとして、S3のネイティブ対応、Postgres対応のSQLクライアント、HTMLインポート機能、スタンドアロンビルドなど、大規模アプリケーション開発にとって便利な機能が数多く追加された。加えて、CSSのバンドリングやプラグインAPIの強化によって、フロントエンド・バックエンドの両面でより高速かつ柔軟な開発体験を提供している。
詳細は公式のリリースノートを参照していただきたい。