---
title: "Hotwireとは？Turbo・Stimulus・Hotwire Nativeの役割とRails 8.1での使い方"
url: "https://www.issoh.co.jp/tech/details/6745/"
published: 2025-05-14
updated: 2026-10-24
categories: ["Ruby on Rails"]
publisher: "株式会社一創"
---

# Hotwireとは？Turbo・Stimulus・Hotwire Nativeの役割とRails 8.1での使い方

Hotwire（ホットワイヤー）は、画面の更新に使うデータをJSONではなく完成済みのHTMLとしてサーバーから送り、ページ遷移やフォーム送信をSPA並みの速さで見せるフロントエンドの手法です。名前は「HTML Over The Wire」の略で、Ruby on Railsの開発元である37signalsが、自社のメールサービスHEYを動かすために作り、2020年12月に公開しました。この記事では、Hotwireを構成するTurbo・Stimulus・Hotwire Nativeの役割分担と2026年10月時点の版、Rails 8.1.4で実際に生成されるファイルとStimulusコントローラの追加手順、Turbo Driveの通常のPOST送信で検証エラーに422を返す理由、ReactやHTMXとの使い分けを、公式ドキュメントとライブラリのソースで確認しながら整理します。

## まとめ：Hotwireの要点

- Hotwireは単一のライブラリではなく、**Turbo（通信と画面差し替え）・Stimulus（小さなJavaScript）・Hotwire Native（モバイルアプリの外枠）**をまとめた呼び名。
- 2026年10月時点の最新版は、Turbo 8.0.23（2026年1月29日）、Stimulus 3.2.2（2023年8月7日）、Hotwire NativeはiOS 1.3.1・Android 1.3.2。
- Rails 7.0以降は`rails new`の既定でturbo-railsとstimulus-railsが入る。Rails 8.1.4でも同じで、外すときは`--skip-hotwire`を付ける。コントローラは`bin/rails generate stimulus 名前`で足せば登録まで済む。
- Turbo Driveの通常のPOST送信に対し、検証エラーのHTMLを直接返す場合は422（Unprocessable Content）を使う。FramesやTurbo Streamsの応答とは区別する。
- 向くのはサーバー側で画面を組み立てる業務アプリや管理画面。オフライン動作や、ブラウザ内で状態を大量に持つエディタ型の画面には向かない。

英語の「hotwire」は、鍵を使わずに配線を直結して車のエンジンをかけることを指し、米国の旅行予約サイトHotwire.comも同じ綴りです。この記事で扱うのは、Web開発のHotwireです。

## Hotwireの仕組み：JSONの代わりにHTMLを送る設計

ReactやVue.jsで組むSPAでは、サーバーはJSONを返し、ブラウザ側のJavaScriptがそのJSONからDOMを組み立てます。Hotwireはこの分担を逆にします。サーバーがテンプレートを描画してHTMLの断片を返し、ブラウザ側はそれを所定の場所に差し込むだけです。公式サイトは、この方式の利点を初回表示の速さと、テンプレートの描画をサーバーに残せることだと説明しています。

| 比較項目          | JSON＋SPA（React等） | Hotwire       |
| ------------- | ---------------- | ------------- |
| サーバーが返すもの     | JSON             | HTML（全体または断片） |
| 画面を組み立てる場所    | ブラウザ             | サーバー（ERB等）    |
| ルーティング        | クライアント側にも持つ      | サーバー側のみ       |
| 状態の置き場所       | ブラウザのストア         | データベースとHTML   |
| 画面更新用JSON API | 構成に応じて設計         | 必須ではない        |

公式サイトは「どのプログラミング言語でも」使える手法だと明記しており、Rails専用ではありません（Rails以外での使い方はFAQで補足します）。

役割の比重も公式が示しています。Stimulusの紹介文には、従来JavaScriptが必要だった操作の「少なくとも80%」はTurboが受け持ち、残りに少量のコードを足すのがStimulusだと書かれています。つまり、Hotwireで書くJavaScriptの大半は「Turboでは足りない部分の補修」です。

## Turbo・Stimulus・Hotwire Nativeの役割分担と2026年10月時点の版

3つの構成要素は担当範囲がはっきり分かれています。版と公開日は、npmレジストリ・RubyGems・GitHubのリリース一覧から取得しました（2026年10月24日時点）。公開履歴：[Turbo](https://github.com/hotwired/turbo/releases)／[Stimulus](https://github.com/hotwired/stimulus/releases)／[Hotwire Native iOS](https://github.com/hotwired/hotwire-native-ios/releases)／[Hotwire Native Android](https://github.com/hotwired/hotwire-native-android/releases)／[turbo-rails（RubyGems）](https://rubygems.org/gems/turbo-rails)

| 構成要素                   | 担当               | 最新版（公開日）           | Rails用gem            |
| ---------------------- | ---------------- | ------------------ | -------------------- |
| Turbo                  | 遷移・フォーム・部分更新     | 8.0.23（2026-01-29） | turbo-rails 2.0.23   |
| Stimulus               | 小さなJavaScriptの整理 | 3.2.2（2023-08-07）  | stimulus-rails 1.3.4 |
| Hotwire Native iOS     | iOSアプリの外枠        | 1.3.1（2026-08-14）  | 不要                   |
| Hotwire Native Android | Androidアプリの外枠    | 1.3.2（2026-10-12）  | 不要                   |

### Turbo 8系の現在地：8.0.0から2年でパッチ23本

Turbo 8.0.0は2024年2月7日に出ており、それ以降はメジャー・マイナーとも上がらず8.0.xのパッチだけが続いています。直近の8.0.23のリリースノートは「前のリリースの古くなった依存を更新してビルドし直した」という一文だけで、APIは変わっていません。turbo-rails gemは2系で番号が別ですが、2.0.23がnpmの@hotwired/turbo-rails 8.0.23と同じ日に出ており、npm版の依存は`@hotwired/turbo ^8.0.23`です。

### Stimulus 3.2.2の公開時期と採用前の確認事項

Stimulusの最新リリースは2023年8月7日の3.2.2で、そこから3年以上新しい版が出ていません。GitHubのmainブランチには2026年7月25日にもコミットがありますが、中身はDependabotによる依存パッケージの版上げ（pbkdf2・got等）と、ハンドブックのリンク削除でした。コントローラ・ターゲット・値・アクションというAPIが3.0（2021年9月）でほぼ固まり、3.2.0（2022年11月）ではOutlets APIが追加され、3.2.2でもPageUp・PageDownのキーマッピングや数値内のアンダースコア対応が追加されています。公開版の更新間隔だけでは、リリースが行われない理由や保守上の懸念の有無は判断できません。採用時は、公開版とmainブランチの差分、未解決の不具合、自社の対象ブラウザでの動作を確認してください。

### Hotwire Nativeの版番号は公式サイトより GitHub が先行

Hotwire Nativeの公式サイト（[native.hotwired.dev](https://native.hotwired.dev/)）は、2026年10月24日時点で「Current iOS version: 1.3.0 — released Jul 7, 2026」「Current Android version: 1.3.1 — released Jul 27, 2026」と表示しています。一方、GitHubにはiOSの1.3.1（2026年8月14日）とAndroidの1.3.2（2026年10月12日）が公開済みです。Androidの1.3.2は、スクリーンショットを正しいウィンドウから取得しシステムメモリの状況に応じて取得を制限する修正と、入れ子のNavigatorHostが別のインスタンスを置き換えるときにナビゲーショングラフを読み込む修正の2件だけで、APIの変更はありません。導入時に指定する版は、公式サイトの表示ではなくGitHubのリリース一覧で確認してください。

## Turboの4つの仕組み：Drive・Frames・Streams・ページリフレッシュ

Turboは、リンクとフォームの扱いを横取りして、ページ全体を読み込み直さずに画面を差し替えるライブラリです。ここでは4つの仕組みを紹介します。Driveとページリフレッシュはページ単位、Framesは特定の領域、Streamsは指定した要素や複数箇所の更新を担います。各機能の詳しい動作は[TurboによるRailsの画面更新の実装](/tech/details/3624/)で、部分更新の実装は[turbo\_frame\_tagの使い方とContent missingの対処](/tech/details/6746/)で扱っています。

### Turbo Drive：fetchによるページ遷移とフォーム送信

Turboを読み込むだけで有効になります。リンクのクリックやフォーム送信をfetchで行い、返ってきたHTMLの`<body>`を差し替え、`<head>`はマージします。CSSとJavaScriptを毎回読み直さないぶん、画面の切り替えが速く見えます。書き換えるコードはゼロです。副作用として、`DOMContentLoaded`は最初の1回しか発火しません。画面遷移ごとに走らせたい初期化処理は`turbo:load`イベントで受けるか、後述のStimulusコントローラに移します。

### Turbo Frames：同じidを持つ領域の部分更新

`<turbo-frame id="...">`で囲んだ領域の中のリンクとフォームは、応答HTMLの中から同じidのフレームを探し、その部分だけを差し替えます。応答に同じidのフレームが無いと、フレームの中に「Content missing」と表示され、コンソールには「did not contain the expected <turbo-frame id=…>」という警告が出ます（Turbo 8.0.23のソースで確認）。インライン編集が動かないときは、まず応答側のフレームidを疑ってください。

```
<%= turbo_frame_tag dom_id(@comment) do %>
  <p><%= @comment.body %></p>
  <%= link_to "編集", edit_comment_path(@comment) %>
<% end %>
```

編集画面（edit.html.erb）側も同じ`turbo_frame_tag dom_id(@comment)`でフォームを囲むと、「編集」を押したときに一覧の中のその行だけがフォームに入れ替わります。

### Turbo Streams：1回の応答による複数箇所の更新

フレームは1か所しか更新できません。フォームを1回送信して「一覧に1件追加し、件数表示も変え、フォームを空に戻す」といった複数箇所の更新をするときは、Turbo Streamsを使います。`<turbo-stream>`要素の`action`属性で操作を指定し、`<template>`の中身を`target`で指定したidの要素に適用します。

```
<turbo-stream action="append" target="comments">
  <template>
    <p id="comment_42">新しいコメント</p>
  </template>
</turbo-stream>
```

Turbo 8.0.23に組み込まれているアクションは、append・prepend・replace・update・remove・before・after・refreshの8つです（パッケージが公開している`StreamActions`のキーを実行して確認）。replaceとupdateには`method="morph"`を付けられ、要素を丸ごと入れ替えずに差分だけを反映できます。HTTP応答として返す場合はContent-Typeを`text/vnd.turbo-stream.html`にします。Action Cable（WebSocket）経由でサーバーから押し出すこともでき、チャットや通知のようなリアルタイム更新はこの経路で作ります。WebSocket自体の仕組みは[WebSocketの仕組みとNode.js実装](/tech/details/15815/)を参照してください。

### ページリフレッシュとモーフィング：Turbo 8で加わった更新方法

Turbo 8で加わった仕組みです。`<head>`に`<meta name="turbo-refresh-method" content="morph">`を置くと、同じページへの再読み込み（ページリフレッシュ）のときに`<body>`を丸ごと入れ替えず、変わった要素だけを書き換えます。既定値は`replace`です。スクロール位置も保ちたい場合は`turbo-refresh-scroll`に`preserve`を指定します。

Railsではturbo-railsの`broadcasts_refreshes`と組み合わせると、どの要素をどう更新するかを1つずつ書かずに済みます。モデルが変わったら「再読み込みせよ」という合図だけを配信し、受け取った画面が自分でリフレッシュする方式です。下の例は既存Boardの更新・削除を購読します。Cardの変更も反映する場合は、Card側に`belongs_to :board, touch: true`などを設定し、Boardの更新を発生させます。

```
# app/models/board.rb
class Board < ApplicationRecord
  has_many :cards
  broadcasts_refreshes
end

<%# app/views/boards/show.html.erb %>
<%= turbo_stream_from @board %>
```

個別のappendやreplaceを並べる方式は、画面の種類が増えるたびにストリームのテンプレートも増えます。複数人が同じ画面を見る看板・ダッシュボード型の画面なら、先にリフレッシュ方式を試し、ページHTMLの再取得による転送量やサーバーの描画負荷が問題になった箇所だけ個別のアクションに切り替えるほうが、書く量を抑えられます。

## Stimulusの書き方：コントローラ・ターゲット・値・アクション

Stimulusは、HTMLに書いた`data-`属性を手がかりに、JavaScriptのクラス（コントローラ）を要素へ結び付けるフレームワークです。DOMを自前で生成せず、サーバーが返したHTMLに振る舞いを足すことだけを担います。次は、テキストエリアの入力長をUTF-16コード単位で数え、上限を超えると出力要素にoverクラスを付けるコントローラです。絵文字などは見た目の1文字とカウントが一致しません。表示を変えるには、overクラスのCSSを別途定義します。

```
// app/javascript/controllers/counter_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["input", "output"]
  static values = { max: Number }

  connect() {
    this.update()
  }

  update() {
    const length = this.inputTarget.value.length
    this.outputTarget.textContent = length
    this.outputTarget.classList.toggle("over", length > this.maxValue)
  }
}
```

```
<div data-controller="counter" data-counter-max-value="140">
  <textarea data-counter-target="input"
            data-action="input->counter#update"></textarea>
  <p><span data-counter-target="output">0</span> / 140</p>
</div>
```

このコードは、Node.js 26.5とjsdom上で@hotwired/stimulus 3.2.2に登録して動かし、上限を10にして13文字を入力すると、出力が「13」になり`over`クラスが付くこと、最初から6文字入っているテキストエリアでは`connect()`の時点で「6」と表示されることを確認しています。

Stimulusの主なAPIは次の6つです。実務でまず覚えるのは上の3つで、残りは必要になってからで足ります。

- **controllers**：`data-controller="counter"`で要素とクラスを結び付ける。Railsでの登録方法は後述の「Stimulusコントローラを追加する手順」で扱う。
- **actions**：`data-action="input->counter#update"`の形で「イベント名->コントローラ名#メソッド名」を指定する。
- **targets**：`static targets`に並べた名前で、`this.inputTarget`のように要素を参照できる。
- **values**：`data-counter-max-value`を型付きで読む。変更時に`maxValueChanged()`が呼ばれる。
- **classes**：付け外しするCSSクラス名をHTML側から渡す。
- **outlets**：別のコントローラを参照する。3.2.0で加わった。

Turbo Driveで画面が差し替わっても、Stimulusは`data-controller`を持つ要素の出現と消滅を監視しているため、`connect()`と`disconnect()`が自動で呼ばれます。前の章で触れた`DOMContentLoaded`の問題は、初期化処理を`connect()`へ移せば起きません。

## Rails 8.1での導入と最小構成

### rails newの既定で入るgemと外し方

Rails 8.1.4（2026年9月24日公開）のアプリジェネレータ（railtiesの`app_base.rb`）は、`--skip-hotwire`が無ければGemfileにturbo-railsとstimulus-railsを書き込み、`importmap:install`の後に`turbo:install stimulus:install`を実行します。JavaScriptの読み込み方式の既定はimportmapで、Node.jsもバンドラも要りません。Ruby 4.0.6で`rails _8.1.4_ new`を実行すると、Gemfile.lockはturbo-rails 2.0.23・stimulus-rails 1.3.4・importmap-rails 2.2.3・rack 3.2.7で固定され、`config/importmap.rb`と`app/javascript/application.js`は次の内容になりました。

```
# config/importmap.rb
pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"

// app/javascript/application.js
import "@hotwired/turbo-rails"
import "controllers"
```

Turboは`import "@hotwired/turbo-rails"`の1行で全ページに効きます。`import "controllers"`が読み込む`app/javascript/controllers/index.js`は、`eagerLoadControllersFrom("controllers", application)`で`pin_all_from`した全コントローラを登録します。

```
# 新規アプリ（Turbo・Stimulus・importmapが入る）
rails new myapp

# Hotwireを入れない
rails new myapp --skip-hotwire

# 既存アプリへ後から入れる
# 前提：importmap-railsまたはjsbundling-railsの導入・設定が完了していること
bundle add turbo-rails stimulus-rails
bin/rails turbo:install stimulus:install
```

Rails以外の環境では、`npm install @hotwired/turbo @hotwired/stimulus`で入れ、エントリーポイントで`import "@hotwired/turbo"`と書くだけでTurbo Driveが動き始めます（パッケージの末尾で`start()`が呼ばれる）。

### Stimulusコントローラを追加する手順：generate stimulusとimportmap

コントローラのファイルは手で作ってもかまいませんが、stimulus-railsのジェネレータを使うと命名の取り違えが起きません。Rails 8.1.4のアプリで実行すると、次のファイルが1つだけ作られます。

```
$ bin/rails generate stimulus counter
      create  app/javascript/controllers/counter_controller.js
```

```
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="counter"
export default class extends Controller {
  connect() {
  }
}
```

importmap構成では、これ以外の作業はありません。`bin/importmap json`の出力に`"controllers/counter_controller"`が加わり、HTML側で`data-controller="counter"`を書けば生成したコントローラが接続されます。前章の文字数カウンターとして動かすには、生成された空のクラスを前章の実装に置き換え、ターゲット・値・アクションを含むHTMLも配置します。名前に`_`や`/`を含めると、data属性では`-`と`--`に置き換わります（`admin/user_list`なら`data-controller="admin--user-list"`）。

jsbundling-rails（esbuild・Bun等）を使う構成では、コントローラの登録が`controllers/index.js`への明示的な`register`になります。ジェネレータは`config/importmap.rb`が無いときだけ`bin/rails stimulus:manifest:update`を自動で実行して`index.js`を書き直します（stimulus-rails 1.3.4のジェネレータのソースで確認）。手でファイルを足した場合は、このコマンドで登録一覧を更新するか、index.jsにimportとapplication.registerを手動で追加します。

開発中の再読み込みには、37signalsの[Hotwire Spark](https://github.com/hotwired/spark)（hotwire-spark gem、最新0.1.13・2025年1月25日）が使えます。`rails new`の既定には入らないので、Gemfileの`group :development`に`gem "hotwire-spark"`を足します。READMEによると、importmap構成ではHTMLの変更をモーフィングで反映し、Stimulusコントローラは変更されたファイルを取得し直してページ内の全コントローラを再読み込みします。バンドラ構成ではHTMLやコントローラの変更時にTurboの画面遷移でページを読み直します。

### フォームのステータスコード：422と303を返す理由

Turbo Driveの導入時には、「バリデーションエラーのときにフォームが再表示されない」という症状に注意が必要です。原因はステータスコードです。Turboのハンドブックは、状態を変更するフォーム送信で通常のHTML応答を返す場合、成功時に303リダイレクトを期待し、検証エラーなどでは4xx・5xxのHTMLを直接描画できると説明しています。POSTの結果を表示した画面を再読み込みすると、ブラウザが再送信の確認を出すためです（Turbo Streamsで応答する場合は別の扱いになります）。Turbo Driveによる通常のPOST送信に、リダイレクトせず200のHTMLを直接返すと、Turbo 8.0.23は「Form responses must redirect to another location」というエラーを出して何も描画しません。

次は、body属性を持つCommentモデル、commentsのルーティング、new・showのビューを用意したアプリから、createとdestroyを抜き出した例です。

```
class CommentsController < ApplicationController
  def create
    @comment = Comment.new(comment_params)
    if @comment.save
      redirect_to @comment, notice: "投稿しました", status: :see_other
    else
      render :new, status: :unprocessable_content
    end
  end

  def destroy
    Comment.find(params[:id]).destroy!
    redirect_to comments_path, status: :see_other
  end

  private

  def comment_params
    params.expect(comment: [:body])
  end
end
```

Rails 8.1.4のscaffoldテンプレートも同じ形で、失敗時は422、updateとdestroyのリダイレクトには`:see_other`（303）を付けています。422を表すシンボルは、Rack 3.1以上なら`:unprocessable_content`、3.1未満なら`:unprocessable_entity`です（Railsの`ActionDispatch::Constants`がRackの版で切り替えている）。古い記事のコードを写すときは、Gemfile.lockのRackの版と合っているか確認してください。

## Hotwire Nativeによるモバイルアプリ開発

Hotwire Nativeは、Webの画面をiOS・Androidアプリの中に表示し、画面遷移やナビゲーションバーだけをネイティブで作るフレームワークです。2024年9月25日に37signalsが発表しました。以前は画面表示を担うTurbo Nativeと、ネイティブ部品との橋渡しを担うStradaに分かれていましたが、発表記事によると「Turbo＋Stimulus＋Stradaの関係がわかりにくい」という声が続いたため、この2つを1つにまとめて改名しています。Turbo Nativeという名前で書かれた資料は、Hotwire Nativeの旧称のものと読み替えてください。

公式ドキュメントは、仕組み・基本のナビゲーション・Path Configuration（URLごとの表示方法の設定）・Bridge Components（Web側から呼べるネイティブ部品）・Native Screens（完全ネイティブの画面）の順に構成されています。Web側で完結する画面の変更を、アプリ本体の再配布なしで反映できる利点があります。ネイティブ側の変更には、アプリ本体の更新が必要です。逆に、カメラ・位置情報・プッシュ通知の細かな制御のように端末機能に深く触れる画面は、Bridge ComponentsかNative Screensでネイティブのコードを書くことになります。Web側の橋渡しに使うnpmパッケージは@hotwired/hotwire-native-bridge（最新1.2.2）です。

Hotwire Nativeが前提にするのは「画面の大半がWebで足りる」アプリです。オフラインで使う画面や、端末機能を使う画面が大半を占めるなら、Web画面を包む方式の利点が薄れます。その場合は、[Flutter・React Nativeによるクロスプラットフォーム開発](/service/apps/cross%5Fplatform/)のように、UIそのものをアプリ側で組む方式と比べて選びます。

## ReactやHTMXとの比較と採用判断

Hotwireとの比較対象には、UIライブラリのReactを使ったSPA構成や、同じHTML返却型のHTMXがあります。HTMXの実装は[htmxの使い方：hx-属性の実装手順](/tech/details/15371/)で扱っています。

| 観点        | Hotwire         | HTMX        | React＋API    |
| --------- | --------------- | ----------- | ------------ |
| サーバーが返すもの | HTML            | HTML        | JSON         |
| ページ遷移の高速化 | 既定で有効           | hx-boostで指定 | ルーターで実装      |
| 書き方       | data属性＋Stimulus | hx-属性       | JSX          |
| リアルタイム配信  | Turbo Streams   | 拡張機能        | 自前実装         |
| モバイルアプリ   | Hotwire Native  | 公式なし        | React Native |
| Rails統合   | 既定で同梱           | gemは有志      | API分離        |

### Hotwireを選ぶべき条件

サーバー側で画面を組み立てるRailsアプリで、画面の大半がフォーム・一覧・詳細の組み合わせなら、Hotwireが第一候補です。フロントエンド専任者がいなくても、ERBとコントローラの延長で画面の部分更新まで書けます。Railsの生みの親であるDHHが、SPA偏重への対案としてこの方式を押し出してきた経緯は[DHHの経歴と設計思想](/tech/details/2908/)にまとめています。

### Hotwireを採用しない場面

次の条件に当てはまる画面では、Hotwireを主軸にしないでください。

- **オフラインで動く必要がある**：新しい画面の取得やサーバーへの保存には通信が必要です。表示済みの画面や履歴キャッシュは利用できる場合がありますが、本格的なオフライン編集・同期には別途設計が必要です。
- **ブラウザ側で大量の状態を持つ**：図形エディタ、表計算、ドラッグ操作の多いカンバンなど。操作のたびにサーバーへ往復すると遅延が体感できる。
- **Web画面もJSON APIとクライアント側の状態管理で揃える方針**：ネイティブアプリや外部連携向けのJSON APIを、Web画面からも同じように使う構成に統一するなら、SPA構成を優先します。APIが必要というだけなら、Hotwireを除外する理由にはなりません。API側の構成は[Rails APIの作成手順とReact連携](/tech/details/2905/)を参照。

一部の画面だけがこれに当たるなら、アプリ全体をSPAにする必要はありません。その画面だけをReactなどで作り、残りをHotwireで作る構成も取れます。Stimulusコントローラの`connect()`でReactのコンポーネントをマウントし、`disconnect()`でアンマウントすれば、Turbo Driveの画面遷移で要素が差し替わっても後始末が漏れません。

## Hotwireに関するよくある質問

### Hotwireは何の略ですか？日本語ではどういう意味ですか？

Web開発のHotwireは「HTML Over The Wire」の略で、「通信路（wire）に乗せてHTMLを送る」という意味です。読み方はホットワイヤーです。英単語の「hotwire」は配線を直結して車のエンジンをかけることを指し、米国の旅行予約サイトHotwire.comとも無関係です。

### HotwireはRails以外（DjangoやLaravel）でも使えますか？

使えます。TurboとStimulusはnpmパッケージ（@hotwired/turboと@hotwired/stimulus）として配布されており、HTMLを返すサーバーであれば言語を問いません。Railsではturbo-railsがビューのヘルパーやストリーム配信を提供します。Rails以外にも、Symfony UX Turboのようにテンプレート部品と配信機能を備える統合があります。ほかのフレームワークでは、コミュニティ製のライブラリを使うか、`<turbo-stream>`のHTMLを自分で組み立てることになります。

### HotwireとReactやVue.jsの違いは何ですか？

JSON APIを使うクライアント描画型のReact・Vue.js構成では、ブラウザ側で画面を組み立てます。Hotwireはサーバーで生成したHTMLを受け取って更新しますが、ReactやVue.jsにもサーバー描画の構成があります。HotwireではAPIとクライアント側のルーティングが要らない代わりに、オフライン動作や、ブラウザ内で大量の状態を持つ画面は苦手です。比較表と採用しない場面は本文の「ReactやHTMXとの比較と採用判断」にまとめています。

### TurboとStimulusの違いは何ですか？

Turboはサーバーとの通信と画面の差し替えを担い、JavaScriptを書かずに動きます。StimulusはTurboでは足りない小さな振る舞い（文字数カウント、開閉、クリップボードへのコピー等）を、HTMLのdata属性とJavaScriptのクラスで書くための仕組みです。まずTurboで書けないかを考え、足りない部分だけをStimulusで書くのが基本の順番です。

### Hotwireでスマホアプリは作れますか？

Hotwire Nativeを使えば、iOSとAndroidのアプリを作れます。Webの画面をアプリ内に表示し、ナビゲーションや一部の部品だけをネイティブで作る方式なので、既存のRailsアプリの画面をそのまま使い回せます。以前のTurbo NativeとStradaは、2024年9月にHotwire Nativeへ統合されました。

## 関連記事

- [Turboとは？Ruby on RailsでHotwireの画面更新を実装する使い方【Turbo 8.0.23】](/tech/details/3624/)
- [Turbo Framesとは？turbo\_frame\_tagの使い方とContent missingの対処【Turbo 8.0.23】](/tech/details/6746/)
- [htmxの使い方：hx-属性の実装手順からFastAPI連携まで解説【2026年版】](/tech/details/15371/)
- [Rails APIとは？作成手順・JWT認証・React連携・Docker環境を実装解説【Rails 8.1】](/tech/details/2905/)
- [DHHとは何者か？Ruby on Rails作者の経歴・設計思想・2026年の現在地](/tech/details/2908/)

---

出典: [Hotwireとは？Turbo・Stimulus・Hotwire Nativeの役割とRails 8.1での使い方](<https://www.issoh.co.jp/tech/details/6745/>)（株式会社一創）
