考える手順
Hotwireの考え方を理解しやすくするために、React, jQuery等と比較して紹介します。
下記のようなUIを作るときのHotwireのアプローチを、Reactと比べながら解説します。
Hotwireの場合は以下のように考えます。
aタグにしますaタグのhref属性の/users/2/user_profileは#user-profileに埋め込むべきHTMLを返してくれるサーバのエンドポイントですaタグのdata-turbo-frameは、サーバから帰ってきたHTMLをどこに埋め込むかを指定していますReactの場合は以下のように考えます。
onclickイベントハンドラを繋げて、クリックしたらselectedUserステートを2に更新しますUserProfileコンポーネントのpropsにステートselectedUser=2を渡し、UserProfileコンポーネントはselectedUser=2に該当するデータをサーバに要求しますUser.id=2に該当するUserの情報をJSONで返しますuserProfileステートにセットされますuserProfileステートを使って、virtual DOMを作成し、新しいUserProfileコンポーネントのHTMLを作りますUserProfileのHTMLと、現在ブラウザに表示されているものを比較して、差分を取り、差分を現在のブラウザ画面に当てはめますselectedUserのステートを設定して、間接的にUserProfileコンポーネントがサーバにデータを取りに行くようにします#user-profileにすぐに埋め込みますuserProfileステートに設定すると、間接的に新しい情報が表示されるようになりますHotwireは目標に対して直接的に処理をしています。一方でReactはまずステートに着目して、これを変更した結果として間接的に UIが更新されるような仕掛けを用意しています。直接的に画面を操作することは許されず、常にステート経由で間接的にUIを更新する仕組みです。
少なくともシンプルなケースにおいては直接的なものがわかりやすいでしょう。一方で複雑になってくれば、間接的にそして宣言的にUIを記述することの意義が出てきます。
参考までにjQueryのやり方を紹介します。
/users/2/user_profileにリクエストが飛ぶようにしますuser-profileに埋め込まれるようにしますjQueryのやり方はHotwireとよく似ていて、直接的です。やはりシンプルでわかりやすいです。
jQueryに対する批判として多かったのは、単純なケースではシンプルである一方で、複雑になるとすぐに混乱してスパゲッティーコード化するというものでした。 一方でHotwireはHTML属性を宣言的に使用しますので、UI/UXが複雑になっても混乱しにくくなっています。
Hotwireと似たアプローチであり、どのバックエンドでも使用できる技術としてはHTMXやAlpine.jsがあります。特にHTMXは注目されていて、Astro, Python, Java Spring, Honoと組み合わせた例がしばしば報告されています。
私も十分にHTMXを試していないのではっきりしたことは言えませんが、Hotwireと比較した場合、大きな違いはHTML属性をどれだけ用意しているかだと感じています。
Hotwireは37signalsの製品で誕生し、実際の製品の複雑なUIでもわかりやすく作るために生まれた技術です。多くの箇所は出来合いのHTML属性だけで対応しますが、必要に応じてカスタムJavaScriptを書くことも重視しています。現実の複雑なプロダクトのエッジケースに対応するため、比較的すぐにJavaScriptを書きます。要するにHotwireは非常に現実主義的です。
それに対して、HTMXはHTML属性中心の宣言的アプローチをより深く追求した、より野心的で学術的なものだと私は感じています。