2025年のJavaScriptランタイム戦争
Node.js一強の時代は終わった。Denoは2.0でnpmパッケージの完全サポートを実現し、Bunは1.1系でNode.js互換性を大幅に向上させた。2025年現在、新規プロジェクトでどのランタイムを選択すべきか。KGAでは3つのランタイムを本番環境で並行運用しており、その経験に基づいた比較を提供する。
起動速度: Bunが圧倒的
スクリプトの起動速度は開発体験とサーバーレス環境でのコールドスタートに直結する。KGAの実測値(同一のTypeScriptファイル、minimal HTTP server)を示す。
Bun 1.1: 12ms。Deno 2.1: 28ms。Node.js 22: 45ms。
Bunの起動速度はNode.jsの約4倍。この差はCLIツールやスクリプト実行で体感できるレベルだ。bun runでpackage.jsonのスクリプトを実行する場合、npm runの約10倍速い。開発中に何百回も実行するコマンドだけに、累積効果は大きい。
HTTPスループット: ベンチマークの落とし穴
単純なHTTPベンチマーク(Hello World)は以下の通り。Bun: 145,000 req/s。Deno: 92,000 req/s。Node.js (fastify): 78,000 req/s。Node.js (express): 32,000 req/s。
しかしこの数値は現実を反映しない。実際のWebアプリケーションでは、DBアクセス、JSON処理、認証、ビジネスロジックが含まれる。KGAの実アプリケーション(REST API、PostgreSQL接続、JWT認証、JSONレスポンス)でのベンチマーク結果は以下の通り。
Bun: 8,200 req/s。Deno: 7,800 req/s。Node.js (fastify): 7,100 req/s。
差は大幅に縮まる。I/Oバウンドな処理ではランタイムの差よりも、DBクエリの最適化やキャッシュ戦略の方がはるかにインパクトが大きい。ランタイムの選択をスループットだけで決めるべきではない。
TypeScriptサポート
Bun: ネイティブでTypeScriptを実行。tsconfigを参照し、型チェックなし(esbuildベースのトランスパイルのみ)で高速実行。ただし型チェックは別途tscを実行する必要がある。
Deno: ネイティブでTypeScriptを実行。Deno 2.0以降はtsconfigのサポートが改善され、strictモードの設定等がより柔軟に。deno checkコマンドで型チェックも可能。
Node.js: v22でexperimental type strippingが導入されたが、まだ実験的。本番環境ではts-nodeまたはtsxを使うのが一般的。ビルドステップ(tsc、esbuild、swc)が必要。
TypeScriptのDX(Developer Experience)ではBunとDenoが明確に優位。ファイルを保存して即実行できる体験は、Node.js + ビルドツールの組み合わせでは得られない。
パッケージ管理とエコシステム
Node.js: npm/yarn/pnpmのエコシステムが最も成熟。npmレジストリに200万以上のパッケージ。ほぼすべてのライブラリがNode.jsをサポート。
Bun: npm互換のパッケージマネージャを内蔵。bun installの速度はnpmの25倍、pnpmの5倍。node_modules構造はnpm互換で、既存のNode.jsプロジェクトの多くがそのまま動作する。ただし一部のネイティブモジュール(node-gyp依存)で互換性問題が残る。KGAのプロジェクトでは、sharp(画像処理)とbcrypt(暗号化)でBun固有の問題に遭遇した。
Deno: npm互換レイヤー(npm:プレフィックス)で大半のnpmパッケージが利用可能。Deno独自のJSR(JavaScript Registry)も提供しているが、パッケージ数はnpmに比べて少ない。Deno 2.0のpackage.json+node_modulesサポートにより、Node.jsからの移行ハードルは大幅に下がった。
バンドルとビルド
Bun: bun buildで高速なバンドルが可能。esbuildの約2倍の速度。ただしwebpackやViteのプラグインエコシステムと比較すると機能は限定的。フロントエンドの複雑なビルドパイプラインには不向き。
Deno: deno compileでスタンドアロンバイナリを生成可能。CLIツールの配布に便利。フロントエンドバンドルにはViteを推奨。
Node.js: Vite、webpack、esbuild、Rollup等の豊富なバンドルツールが利用可能。フロントエンド開発のツールチェーンは依然としてNode.jsが最も充実。
KGAの使い分け戦略
- ランタイムの使い分けはプロジェクトの性質で決める。既存のNode.jsプロジェクト: Node.jsを継続。移行リスクに見合うメリットは現時点で少ない。新規のバックエンドAPI: Bunを第一候補。起動速度とTypeScriptのDXが優秀。ただしNode.js互換性の問題に注意。CLIツール・スクリプト: Deno。パーミッションモデルのセキュリティ、deno compileのバイナリ配布が便利。フロントエンド開発: Node.js(Viteのエコシステム)。Bunも対応しているが、Viteプラグインの互換性問題が残る。
移行時の注意点
Node.jsからBunへの移行では、package.jsonとnode_modulesの互換性が高いため、多くのケースでbun installしてbun run devで動作する。KGAの10プロジェクト中8プロジェクトで即座に動作した。残り2プロジェクトはネイティブモジュールの互換性問題で修正が必要だった。
Node.jsからDenoへの移行は、Deno 2.0の互換性改善により以前より容易になったが、CommonJS(require)からESM(import)への移行が最大の障壁。既存のNode.jsプロジェクトがCommonJSを多用している場合、移行コストは無視できない。新規プロジェクトで採用するか、段階的に移行するのが現実的だ。