generated at
Node.js, Deno, Bunの比較 - どれを使うべきか?
はじめに
DenoBunなどの登場により、どのランタイムを使うべきなのかに関する意見や疑問などを見かける機会が増えてきたような気がしました
このページでは、各ランタイムへの個人的な印象や意見などについてまとめてみます
私の考えとして、以下のような立場で意見をまとめています
サーバーサイドランタイムとしてのNode.jsには概ね満足していて、大きな不満は特にない
スクリプティングランタイムとしてのDenoはかなり気に入っている

TL;DR
最初に結論だけ書いてしまうと、現時点(2024年)では、業務におけるフロントエンド・バックエンド開発においては、DenoBunの採用はまだ早いと思っています (将来的にはDenoBunのどちらもNode.jsとの互換性がより改善され、いずれにしても移行も楽になると思われるので、現状ではNode.jsを使って様子見しておくのが安全ではないかと思っています)
ただし、CLIツールの開発やスクリプティング、Vimプラグインの開発(denops.vim)などの分野であれば、DenoBunは使い勝手がとても良いと思っており、採用も十分アリだと思います
もし現時点でDenoBunを業務におけるフロントエンド・バックエンド開発に採用したいという場合は、まずはリスクの低い箇所(スクリプティング、社内システム/ツール、Slackなどのチャットボット、Faasにおける特定のFunctionなど)に対して局所的に採用して評価や検討をした上で、段階的に採用を進めていくのが個人的には良いと思います

それぞれのよい点について
Node.jsのよいところ
(2024年時点) 誕生から15年近く経過しており、大規模なサービスなどでの使用実績も豊富にあり、最も高い安定性が期待できる
(2024年時点) 基本的にフロントエンドのエコシステムの多くはNode.jsを想定して開発されているため、最新のツールなども安定して動かしやすい
DenoBunで導入された独自の機能についても少しずつ導入または検討が進められています
パーミッションシステム
.envのサポート
pnpmではv10.0.0からDeno--allow-scriptsBuntrustedDependencies相当の仕組みが導入されています

Denoのよいところ
Deno Deployとその周辺サービス(Deno KV, Deno Queuesなど)やエコシステムの存在、後述のパーミッションシステムなどもあり、バックエンド開発においてはBunよりDenoの方がやや有利な印象
また、SlackNetlifyなどがFaaSの基盤としてDeno Deploy (Deno Subhosting)の採用を進めていることも大きいと思います (Denoの使用事例)
パーミッションシステムやprototype汚染攻撃への対策, ロックファイル(deno.lock)など、セキュリティを意識した仕組みが提供されていること
ただ現状では多くの場合、 deno run -A で実行されるケースが比較的多いのではないかとも思うので、パーミッションシステムの存在が他のランタイムと比較したときに、どれほどメリットになるのかは正直わからないです
パッケージレベルでパーミッションを制御したいという要望はいくつか上がっていて、これがサポートされると実用度が上がる可能性はあるかもしれないと思いました (https://github.com/denoland/deno/issues/171)
TypeScriptのネイティブサポート
スクリプトを実行する際に、Denoが自動でTypeScriptコードをトランスパイルしてくれます
tscが組み込まれており、deno checkdeno testなどのコマンドを使うことで、型チェックも行えます
deno_std (jsr.io/@std)によって様々な機能が提供されている
Jupyterとの連携(deno jupyter)
WebGPU APIのサポート
また、Deno独自の機能としてWebGPU APIをベースにしたBYOWという機能があります
Web標準との互換性の高さ
元々、DenoはWeb標準への準拠を重視していたこともあり、この分野ではDenoが一番優位だと思う (2024年時点)
Node.jsとの互換性
(2024年時点) 最初からNode.jsとの互換性を念頭において設計・開発されている分、この点ではBunの方が有利だと思う
jsrのネイティブサポート
WASMモジュール (Deno v2.1)
deno lintdeno fmt, deno lsp, TypeScriptサポートなどがランタイムに組み込まれていることや、リモートモジュールの import の手軽さなど、初期セットアップなどの手間がとても少なく、スクリプティングにおける体験がとてもよい
自分はスクリプティングでの体験の良さを気に入ってDenoを使い始めたので、これが個人的には一番よい点だと思う
ただし、BunBun Shellを実装したように、この点におけるDenoBunの差は少しずつ縮んでいく可能性もあるとは思う
deno fmtにおけるYAML/CSS/HTML/Vue.js/Svelteなどのサポート
Vimプラグインが書ける (denops.vim)
ただcoc.nvimなどを使えば、Node.js書くことは可能です (おそらくBunでも書けると思います)

Bunのよいところ
元々、Node.jsとの互換性を重視して開発されたこともあり、Node.jsとの互換性ではDenoよりもBunの方が有利だと思う
TypeScriptのネイティブサポート
ただし、Denoとは異なり、型チェックについては別途、tscを使う必要あり
(2024年時点) フロントエンド開発で使用するなら個人的にはDenoよりもBunの方が有利だと思う
パフォーマンスの高さやNode.jsとの互換性の高さ, バンドラーの提供(bun build)などが理由
Bunにはdeno fmt/deno lint相当のコマンドはないものの、本格的にフロントエンド開発などをやるのであれば現状ではeslintprettierなどのカスタマイズ性の高さは重要だと思うので、そこまで問題にはならないはず (フロントエンド開発においては、Denoが提供するdeno fmt/deno lintなどの仕組みは、現状ではそこまでメリットにはならないというのが個人的な考え)
Bun Shellと組み込みでのTypeScriptサポートなどによるスクリプティングでの体験のよさ
バンドラーを組み込みで提供している (bun build)
セキュリティ (trustedDependenciesなどの仕組みがある)
SQLiteのサポート (bun:sqlite)
PostgreSQLのサポート (Bun.sql)
S3のサポート (v1.1.43)
(おそらく意図的なものなのだとは思いますが) Bunは標準などから大きく外れた独自機能を導入することが多々あり、人によって好き嫌いが分かれやすい部分だとは思いますが、気にいる人にはかなり刺さる特徴なのではないかと思います
例)
package.jsonでのコメントの記述のサポート (https://bun.sh/blog/bun-v1.1.5)
SQLiteデータベースの import (bun:sqlite)

所感
個人的な好み
スクリプティングやCLIツールの開発における使い勝手や体験の良さ、Web標準への準拠など、私はDenoはとても気に入っています
特にスクリプティングにおいての体験が素晴らしく、定型的な作業の効率化などではとても便利だと思っています

どれを採用するのが良いか?
先程、自分はDenoをとても気に入っているとは書きましたが、現時点(2024年)では、業務でのWeb開発においては、まだNode.jsを使うべきだと個人的には思っています
Node.jsにはいくつかの欠点があり、DenoBunがそれを修正しようとしていることも事実だとは思うものの、Node.jsにはその欠点を補うだけの膨大なエコシステムやコミュニティがあります
また、Node.jsも進化が止まっているわけではなく、継続的にそういった欠点などの改善も試みられています
Node.jsは現状では最も安定性が高く、開発においてつまずく可能性も低い
ただし、これはあくまでDenoBunと比較した場合での話です
私個人の印象として、Node.jsはエコシステムがやや乱立しがち※であり、労力などが分散してしまう分、個々のORMやフルスタックフレームワークなどのバックエンド開発において必要となるライブラリの成熟度では、RailsJava, C#あたりと比較するとどうしてもやや低くなりがちな印象があります。ただでさえそのあたりでのリスクがある上でWeb開発においてDenoBunなどを採用するのは、現状では正直かなりリスキーであると個人的には思います
※乱立しがちであるというのは選択肢が多いというメリットとも考えられるため、一概に悪いことであるとは言えないとも思います
例えば、以下の記事などでも言及されているように、プロダクトのコアに十分に検証していない技術を採用することには大きなリスクがあり、また当初期待していた程のメリットを得られない可能性もある (新しい技術を採用した結果、却ってそれが負債となってしまう可能性がある)
DenoBunが強みとして打ち出している様々な要素は実際に魅力的であるとは思うものの、もし採用を検討する際は、まず事前にきちんと検証や調査などをしてから採用を判断すると安全だと思います
現時点でDenoBunをWeb開発で本格的に使おうとする場合、「〜のnpmパッケージが動かない」「Node.jsと異なる振る舞いをする」「〜を実現するライブラリがまだない」「アップデートしたら〜のnpmパッケージが動かなくなった」などといったリスクがまだまだ発生すると思います。どちらもBetter Node.jsとして使うには、まだ安定性は足りていないと個人的には思っています
また、現状、Node.jsがこれだけ広く使われている以上、DenoBunの影響で相対的に需要が低下することはあったとしても、Node.jsが完全に使われなくなるということは考えにくいと思っています
将来的にNode.js/Deno/Bunのどれがメジャーになるかは正直わからないものの、少なくともNode.jsの需要が完全になくなってしまうという可能性は低いのではないかと思っています
ScalaKotlinが登場してもJavaは生き残り続けており、採用している言語が同じである以上、DenoBunの影響でNode.jsが完全にオワコン化してしまうといったような可能性はかなり低いと思っています
DenoBunにはNode.jsにはないメリットが多くあることは事実だとは思うものの、業務におけるバックエンドやフロントエンドの開発においてはまだ時期尚早だと思う (2024年時点)
例えば、大規模なB2Bサービスの開発で採用することなどを考えた際に、DenoBunが提供するメリットは、Node.jsが提供する安定性やシェア、情報量が豊富であることなどのメリットを現状では上回らない、というのが個人的な考えです (現状では正直、苦労することの方が多いと思います)
Deno DeployDenoをWeb開発で採用する上での最大のメリットであり、Node.jsBunとの差別化の上でも重要なものだと思っています。しかし、このDeno Deployは2024/05時点ではまだGA版がリリースされていません (今後、破壊的変更などが生じる可能性もまだ考えられます)
また、Deno Deployが提供するDeno KVは、キャッシュやPub/Sub、メッセージングなどの選択肢の一つとしては悪くはないとは思うものの、大規模なサービスにおける永続化層として全面的に採用するには正直やや心許ないというのが個人的な印象です。(特に数百〜数千以上ものテーブルが必要となるような大規模なB2Bサービスの開発などにおいては、例えば関係データベースが提供するリレーションやトランザクション、行レベルセキュリティなどの仕組みは非常に有用だと思っています)
しかし、永続化層として関係データベースを採用しようとすると、今度はDeno Deployのメリットが活かしづらくなるジレンマが発生します...
このあたりは各種NewSQLであったりTursoなどの技術が発達していくと改善されていく可能性はあるのかもしれないですが、正直どうなるのかはちょっとまだわからないです
永続化レイヤーはコンピューティングレイヤーと比較して、リファクタリングなどに膨大なコストがかかってしまうケースが多いと思うので、意思決定は慎重に行うと安全ではないかと思っています
現時点では、もし採用する場合は、Deno KVに適していると思われる小規模なアプリでの採用や部分的な採用がよいのではないかと思っています
また、Deno/Bun/Node.jsはどれも採用している言語が同じで かつ npmという同一のエコシステムにも依存していることもあり、Node.jsと比較した場合のDenoBunの現状での安定感から判断すると、ランタイムに関してあえてリスクを犯してまで新しいものに乗っかるメリットが正直そこまで大きくない、という事情もあります (JavaScala/Kotlinなどにおける例とは異なり、採用している言語が同じなので、差別化できる要素が少ない)
Node.jsも別にレガシーなプロダクトというわけではなく、現在でも積極的に新しいものが開発されています
ただし、Deno DeployではDeno KVDeno Queues, Deno Subhostingなど、少しずつ機能やサービスが拡充されつつあります。今後、Deno Deployに有用な機能やサービスなどが順調に増えていけば、十分選択肢にはなりうるのではないかと思っています。(ただ、現時点での採用はまだ早いとはおもいます...)
新しい技術を採用したからといって、必ずしも既存の課題や問題が魔法のように解決するとは限らないです。Hype Driven Developmentに陥ってしまわないように注意するとよいでしょう。実際に採用するかどうかは、評判などだけで判断するのではなく、きちんと検証や調査を実施してから判断するのがよいと思います。
参考までにDenoの使用事例をまとめているため、よろしければこちらなども参照ください🙇‍♂️
また、Denoには開発初期のセットアップ作業がかなり楽になるというメリットはあるものの、実際のWeb開発においてはそう何度も初期セットアップを行うようなことはまれなはずなので、そこまで恩恵はないと思われます (ただし、スクリプティングなどにおいてはこのメリットの恩恵は受けやすいはず)
DenoBunが提供するネイティブでのTypeScriptサポートも、正直、Web開発においてはそこまで大きなメリットにはならないと思います
こういった機能はWeb開発ではなく、どちらかといえばスクリプティングなどの方が恩恵を受けやすいと思います
また、Node.jsにおいてもTypeScriptのサポートが検討されつつあります (Node.jsにおけるTypeScriptサポートについて)
個人的にDenoが提供するdeno fmtコマンドは非常に魅力的であると考えています
しかし、もう一方のdeno lintコマンドについては、正直Web開発においてはESLintの方が優位性が高いと思っています
ESLintにおける数々の有用なプラグインによって提供される価値は、deno lintが提供するパフォーマンス上の優位性よりも上回ると個人的に考えています
後述するように、Node.jsでは、おそらくDenoBunの影響を受けて、パーミッションシステムなどの機能の導入が少しずつ進んでいます
数年後には、Node.jsにおいてもDenoBunが提供している機能を利用できるようになる可能性が考えられます
また、数年後にはDenoBunはどちらももNode.jsとの互換性がさらに改善されているはずなので、もしNode.jsからそれらへ移行をしたいというようなケースが出てきたとしても、将来的にはハードルは下がっている可能性が高いと思います
ただし、スクリプティングやCLIツール、Vimプラグインなどの開発ではDenoBunはかなり使い勝手が良く、この分野での採用は現状でも十分にアリだと思います
なので、もしDenoBunの採用を考える場合は、このあたりから少しずつ進めていくのがよいと思っています

DenoをWeb開発で採用するなら
Node.jsBunと比較した際に、Web開発でDenoを採用する最大のメリットはDeno Deployの存在だと思います
Denoには他にもパーミッションシステムなどの機能はあるものの、この機能はNode.jsにおいても実装が進みつつあるため、差別化要素としてはやや弱めと見ています
そのため、Deno Deployやその周辺サービスであるDeno KVなどを活用しやすいプロダクトであれば相性は良いのではないかと思います
具体的には、永続化に関する要件が厳しくなく、Deno KVでも十分にワークするようなケースなど (小規模なプロダクトや社内プロダクト、Webサイトなど)
その他には、Supabase (Supabase Edge Functions)やNetlify (Netlify Edge Functions)などを採用したプロダクトにおいて部分的に採用するのも悪くないと思います

Bunを採用する場合
BunDenoに対するメリットとして、Node.jsの単純な置き換えとして考えた際のパフォーマンスの高さやフロントエンド開発との相性(bun buildなど)が上げられると思います
ただ、もし採用するとしても、当面はCINode.jsBunの両方で同じテストなどを実行しておき、何か問題があった際にすぐにNode.jsへロールバックできるようにしておくと安全ではないかと思います

DenoBunはどちらがよい?
これは用途や好みなどによって異なってくるのではないかと思っています
スクリプティングにおいては、ややDenoが有利ではないかと思っています
Deno: 外部ライブラリを手軽に利用でき、deno lintdeno fmtなどのコマンドがあらかじめ組み込まれており、取り回しがしやすい
Bun: Bun shellがあるのがメリット
CLIツールを作成したい場合は、双方にメリットがあり、どちらにもそこまで差はないと思います
DenoBunはどちらもスタンドアロンの実行可能ファイルを作成する機能を提供している (deno compile/ bun build --compile )
Deno https: npm: などによるライブラリの import や動的なダウンロードなどの機能があります。この仕組みにはプラグインシステムを備えたアプリケーションを開発したい場合、外部ライブラリに依存したプラグインを開発・配布しやすいというメリットがあると考えられます。こういったプラグインシステムを提供するCLIアプリなどを開発する場合、Denoはとても相性が良いのではないかと思います (実際にdenops.vimではその仕組みが活用されています)
BunはデフォルトでSQLiteドライバーを提供している (bun:sqlite)
フロントエンドでSPAを開発したいケースなどではBunの方が向いているのではないかと思っています
バンドラー(bun build)やesbuildライクなプラグインAPIの提供など、フロントエンド周りについてはDenoよりもBunの方が重視されている印象があります
Deno Deployの存在もあり、バックエンド開発についてはDenoの方が取れる選択肢はやや多いはず
後はdeno jupyterWebGPU APIなどのサポートもあり、データサイエンス周りではDenoがやや有利なはず?(この分野は自分はあまり詳しくないため、実際のところどうなのかはちょっと自信なしです...)
Web開発以外の用途での使用においては、deno jupyterWebGPU APIの存在など、Denoの方がやや重要視されているような印象はあります

標準への準拠について
Node.js/Deno/BunのどのランタイムでもWeb標準への準拠少しずつが進められている または 重視されています
また、WinterCGでは各ランタイムでのAPIなどを標準化するための取り組みが行われています
Node.jsでは (おそらくDenoBunの影響もあって) パーミッションシステムの実装や単一実行可能ファイルの作成などのサポートが進められつつあります
こういった動きもあり、将来的にはそれぞれのランタイム間の差異は徐々に縮まっていく可能性は比較的高いのではないかと思う
現時点では、できるだけこういった標準に準拠している または しやすい選択肢を採用しておくと、今後の変化に対応しやすいのではないかと思う (Remix, Honoなど)

終わりに
私の意見としては、バックエンドやフロントエンドの開発においてNode.jsではなくDenoBunを採用するのは現時点ではまだリスキーであると思っています (ただし、CLIやスクリプティングなどにおけるDenoBunの部分的な採用は現時点でもありだと思っています)
ただし、どのランタイムもWeb標準への対応は少しずつ改善されつつあります。また、HonoRemixなどのWeb標準を意識したフレームワークも登場しています。
その他にもWinterCGなどの登場により、各ランタイム間での標準化が少しずつ進んでいく可能性も考えられます。また、HonoElysiaなど、WinterCGを意識したフレームワークも登場しています。
これらの標準への対応などにより、Node.jsDeno, Bunなどの各ランタイムの相互運用製が徐々に改善していく可能性もあります
これから相互運用性が少しずつ改善されていけば、各ランタイムの移行や併用などはしやすくなってくると思っており、それまでは本格的な採用は見送る方が安全なのではないかと個人的には思っています
正直、今後、どれが最も人気になるのかはわからないですが、少なくともNode.jsの需要が完全になくなってしまうということは考えにくいのではないかと思っています
DenoBunNode.js互換性の改善にはかなり力が入れられているので、今、急いで採用や移行などをしなくとも、数年後にはよりスムーズに移行や採用などがしやすくなるはずです
少し批判的な内容も書いてしまいましたが、DenoBunもかなり注目は浴びており、コミュニティなども活発に見えるため、個人的にはどちらもかなり期待しています
私はDenoをスクリプティングの用途で日々使っていて、とても使い勝手がよく感じています。DenoにせよBunにせよ、現時点ではWeb開発への採用は少しリスキーではあると思うので、もし興味がある際は、まずはスクリプティングなどの小さな部分から少しずつ採用していくと良いのではないかと思っています

関連ページ