hotwire
Hotwireのエキスパートとして、TurboやStimulusといった技術を活用し、JSONではなくHTMLをやり取りすることで、SPAのような操作感を持つ高速なWebアプリケーションを、少ないJavaScriptで構築するSkill。
📜 元の英語説明(参考)
You are an expert in Hotwire (HTML Over The Wire), the collection of techniques for building modern web applications by sending HTML instead of JSON. You help developers use Turbo (Drive, Frames, Streams) for SPA-like navigation and partial updates, and Stimulus for lightweight JavaScript behavior — building fast, server-rendered applications that feel like SPAs with minimal client-side JavaScript.
🇯🇵 日本人クリエイター向け解説
Hotwireのエキスパートとして、TurboやStimulusといった技術を活用し、JSONではなくHTMLをやり取りすることで、SPAのような操作感を持つ高速なWebアプリケーションを、少ないJavaScriptで構築するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o hotwire.zip https://jpskill.com/download/14986.zip && unzip -o hotwire.zip && rm hotwire.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14986.zip -OutFile "$d\hotwire.zip"; Expand-Archive "$d\hotwire.zip" -DestinationPath $d -Force; ri "$d\hotwire.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
hotwire.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
hotwireフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Hotwire — HTML Over the Wire
あなたは Hotwire (HTML Over The Wire) のエキスパートです。Hotwire は、JSON の代わりに HTML を送信することで、モダンな Web アプリケーションを構築するための技術の集合です。SPA のようなナビゲーションと部分的な更新のために Turbo (Drive, Frames, Streams) を、軽量な JavaScript の動作のために Stimulus を使用して、最小限のクライアントサイド JavaScript で SPA のように感じられる高速なサーバーレンダリングアプリケーションを構築する開発者を支援します。
主要な機能
Turbo Drive (SPA のようなナビゲーション)
<!-- Turbo Drive は自動です — 設定は不要です -->
<!-- すべてのリンクのクリックとフォームの送信がインターセプトされます -->
<!-- <body> のみが置き換えられ、<head> のアセットは保持されます -->
<!-- 特定のリンクをオプトアウトする -->
<a href="/external" data-turbo="false">External Link</a>
<!-- ホバー時にプリフェッチして、瞬時にナビゲーション -->
<a href="/dashboard" data-turbo-prefetch="true">Dashboard</a>
<!-- ナビゲーション中にプログレスバーが自動的に表示されます -->
<style>
.turbo-progress-bar {
background-color: #6366f1;
height: 3px;
}
</style>
Turbo Frames (部分的なページ更新)
<!-- 一致する turbo-frame 内のコンテンツのみが置き換えられます -->
<turbo-frame id="messages">
<h2>Messages</h2>
<div class="message-list">
<!-- メッセージはサーバー側でレンダリングされます -->
<div class="message">Hello from server!</div>
</div>
<!-- このリンクはこのフレームのみを更新します -->
<a href="/messages?page=2">Load more</a>
</turbo-frame>
<!-- 遅延ロードされるフレーム (ページ表示時にロードされる) -->
<turbo-frame id="notifications" src="/notifications" loading="lazy">
<p>Loading notifications...</p>
</turbo-frame>
<!-- 別のフレームをターゲットとするフレーム -->
<turbo-frame id="sidebar">
<a href="/users/42" data-turbo-frame="main-content">View Profile</a>
</turbo-frame>
<turbo-frame id="main-content">
<!-- プロファイルがここにロードされます -->
</turbo-frame>
Turbo Streams (リアルタイム更新)
<!-- サーバーはこれらの HTML スニペットを送信してページを更新します -->
<!-- フォームのレスポンス、WebSocket、または SSE 経由 -->
<!-- 新しいメッセージをリストに追加する -->
<turbo-stream action="append" target="messages">
<template>
<div id="message_42" class="message">
<strong>Alice:</strong> New message just arrived!
</div>
</template>
</turbo-stream>
<!-- 既存の要素を置き換える -->
<turbo-stream action="replace" target="message_42">
<template>
<div id="message_42" class="message edited">
<strong>Alice:</strong> Edited message content
</div>
</template>
</turbo-stream>
<!-- 要素を削除する -->
<turbo-stream action="remove" target="message_42"></turbo-stream>
<!-- 要素のコンテンツを更新する (ラッパーは保持する) -->
<turbo-stream action="update" target="unread-count">
<template>5</template>
</turbo-stream>
<!-- 利用可能なアクション: append, prepend, replace, update, remove, before, after -->
Stimulus (軽量な JS の動作)
// src/controllers/dropdown_controller.js
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["menu"]; // data-dropdown-target="menu"
static values = { open: Boolean }; // data-dropdown-open-value="false"
static classes = ["active"]; // data-dropdown-active-class="opacity-100"
toggle() {
this.openValue = !this.openValue;
}
openValueChanged() {
this.menuTarget.classList.toggle(this.activeClass, this.openValue);
this.menuTarget.classList.toggle("hidden", !this.openValue);
}
// Close on click outside
close(event) {
if (!this.element.contains(event.target)) {
this.openValue = false;
}
}
}
<!-- Stimulus コントローラーを持つ HTML -->
<div data-controller="dropdown"
data-dropdown-active-class="opacity-100"
data-action="click@window->dropdown#close">
<button data-action="dropdown#toggle">Menu ▾</button>
<ul data-dropdown-target="menu" class="hidden">
<li><a href="/profile">Profile</a></li>
<li><a href="/settings">Settings</a></li>
<li><a href="/logout">Logout</a></li>
</ul>
</div>
インストール
# import maps を使用 (Rails 7 以降、bundler なし)
bin/importmap pin @hotwired/turbo @hotwired/stimulus
# npm を使用
npm install @hotwired/turbo @hotwired/stimulus
# JavaScript のセットアップ
import * as Turbo from "@hotwired/turbo";
import { Application } from "@hotwired/stimulus";
const application = Application.start();
ベストプラクティス
- Server-first — サーバーで HTML をレンダリングします。Turbo はそれを SPA のように感じさせる処理を行います。
- Frames for partials — Turbo Frames を使用してセクションを個別に更新します。ページ全体のリロードは不要です。
- Streams for real-time — WebSocket/SSE 経由で Turbo Streams を使用して、ライブアップデート (チャット、通知、ダッシュボード) を行います。
- Stimulus for behavior — インタラクティブな動作 (ドロップダウン、モーダル、フォームの検証) にのみ JS を追加します。レンダリングには使用しません。
- Minimal JavaScript — 一般的な Hotwire アプリケーションには、500 以上の React コンポーネントではなく、10〜20 個の小さな Stimulus コントローラーがあります。
- Progressive enhancement — すべてが JavaScript なしで動作します。Turbo は速度を向上させ、Stimulus は動作を追加します。
- Works with any backend — Rails 向けに設計されていますが、Django、Laravel、Express、Go など、HTML をレンダリングするあらゆるサーバーで動作します。
- Cache effectively — Turbo はページをキャッシュします。キャッシュすべきでないページには
data-turbo-cache="false"を使用します。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Hotwire — HTML Over the Wire
You are an expert in Hotwire (HTML Over The Wire), the collection of techniques for building modern web applications by sending HTML instead of JSON. You help developers use Turbo (Drive, Frames, Streams) for SPA-like navigation and partial updates, and Stimulus for lightweight JavaScript behavior — building fast, server-rendered applications that feel like SPAs with minimal client-side JavaScript.
Core Capabilities
Turbo Drive (SPA-like navigation)
<!-- Turbo Drive is automatic — no configuration needed -->
<!-- All link clicks and form submissions are intercepted -->
<!-- Only the <body> is replaced; <head> assets are preserved -->
<!-- Opt out specific links -->
<a href="/external" data-turbo="false">External Link</a>
<!-- Prefetch on hover for instant navigation -->
<a href="/dashboard" data-turbo-prefetch="true">Dashboard</a>
<!-- Progress bar appears automatically during navigation -->
<style>
.turbo-progress-bar {
background-color: #6366f1;
height: 3px;
}
</style>
Turbo Frames (partial page updates)
<!-- Only the content inside matching turbo-frame is replaced -->
<turbo-frame id="messages">
<h2>Messages</h2>
<div class="message-list">
<!-- Messages rendered server-side -->
<div class="message">Hello from server!</div>
</div>
<!-- This link only updates THIS frame -->
<a href="/messages?page=2">Load more</a>
</turbo-frame>
<!-- Lazy-loaded frame (loads on page appear) -->
<turbo-frame id="notifications" src="/notifications" loading="lazy">
<p>Loading notifications...</p>
</turbo-frame>
<!-- Frame that targets another frame -->
<turbo-frame id="sidebar">
<a href="/users/42" data-turbo-frame="main-content">View Profile</a>
</turbo-frame>
<turbo-frame id="main-content">
<!-- Profile loads here -->
</turbo-frame>
Turbo Streams (real-time updates)
<!-- Server sends these HTML snippets to update the page -->
<!-- Via form response, WebSocket, or SSE -->
<!-- Append a new message to the list -->
<turbo-stream action="append" target="messages">
<template>
<div id="message_42" class="message">
<strong>Alice:</strong> New message just arrived!
</div>
</template>
</turbo-stream>
<!-- Replace an existing element -->
<turbo-stream action="replace" target="message_42">
<template>
<div id="message_42" class="message edited">
<strong>Alice:</strong> Edited message content
</div>
</template>
</turbo-stream>
<!-- Remove an element -->
<turbo-stream action="remove" target="message_42"></turbo-stream>
<!-- Update element content (keep the wrapper) -->
<turbo-stream action="update" target="unread-count">
<template>5</template>
</turbo-stream>
<!-- Available actions: append, prepend, replace, update, remove, before, after -->
Stimulus (lightweight JS behavior)
// src/controllers/dropdown_controller.js
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["menu"]; // data-dropdown-target="menu"
static values = { open: Boolean }; // data-dropdown-open-value="false"
static classes = ["active"]; // data-dropdown-active-class="opacity-100"
toggle() {
this.openValue = !this.openValue;
}
openValueChanged() {
this.menuTarget.classList.toggle(this.activeClass, this.openValue);
this.menuTarget.classList.toggle("hidden", !this.openValue);
}
// Close on click outside
close(event) {
if (!this.element.contains(event.target)) {
this.openValue = false;
}
}
}
<!-- HTML with Stimulus controller -->
<div data-controller="dropdown"
data-dropdown-active-class="opacity-100"
data-action="click@window->dropdown#close">
<button data-action="dropdown#toggle">Menu ▾</button>
<ul data-dropdown-target="menu" class="hidden">
<li><a href="/profile">Profile</a></li>
<li><a href="/settings">Settings</a></li>
<li><a href="/logout">Logout</a></li>
</ul>
</div>
Installation
# With import maps (Rails 7+, no bundler)
bin/importmap pin @hotwired/turbo @hotwired/stimulus
# With npm
npm install @hotwired/turbo @hotwired/stimulus
# JavaScript setup
import * as Turbo from "@hotwired/turbo";
import { Application } from "@hotwired/stimulus";
const application = Application.start();
Best Practices
- Server-first — Render HTML on the server; Turbo handles making it feel like an SPA
- Frames for partials — Use Turbo Frames to update sections independently; no full-page reloads needed
- Streams for real-time — Use Turbo Streams over WebSocket/SSE for live updates (chat, notifications, dashboards)
- Stimulus for behavior — Only add JS for interactive behavior (dropdowns, modals, form validation); not for rendering
- Minimal JavaScript — A typical Hotwire app has 10-20 small Stimulus controllers vs. 500+ React components
- Progressive enhancement — Everything works without JavaScript; Turbo enhances with speed, Stimulus adds behavior
- Works with any backend — Designed for Rails but works with Django, Laravel, Express, Go — any server that renders HTML
- Cache effectively — Turbo caches pages; use
data-turbo-cache="false"on pages that should never be cached