目次

  1. 結論(早見表)
  2. それぞれの設計思想
  3. 判断軸ごとの比較
  4. 技術ごとの「向いている/向いていない」
  5. 組み合わせ方のベストプラクティス
  6. 選定フローチャート
  7. 選定時のチェックリスト
  8. まとめ

1. 結論(早見表)

状況第一候補
Rails 等のサーバーサイドレンダリング中心で、画面に「少しの動き」を足したいStimulus(+ Turbo)
既存のサーバーレンダリング画面の一部に、状態を持つリッチなUIを埋め込みたいVue(部分導入)
中〜大規模の SPA、または小規模ながら複雑なUIVue または React
大規模チームでの長期開発、エコシステムや採用市場を重視React
モバイルアプリ(React Native)とコードや知見を共有したいReact
チームにフロントエンド専任がいない/バックエンド中心のチームStimulus → 足りなければ Vue

原則:「HTML をどこで作るか」で決める。

  • サーバーが HTML を作る → Stimulus(JS は振る舞いを足すだけ)
  • ブラウザが HTML を作る → Vue / React(JS が状態から DOM を描画する)

2. それぞれの設計思想

Stimulus

  • HTML が主役。サーバーから返った HTML に data-controller / data-action / data-target 属性でJSの振る舞いを紐づける。
  • 状態は基本的に DOM(data属性・クラス・フォーム値)に持つ。JS側でアプリケーション状態を管理しない。
  • Hotwire(Turbo)と組み合わせ、画面遷移や部分更新はサーバーから HTML を返して実現する。
  • ビルド不要(importmap)でも始められ、学習コストが非常に低い。

Vue

  • リアクティブな状態 → テンプレート描画。HTML に近いテンプレート構文で、デザイナーやバックエンドエンジニアにも読みやすい。
  • 既存ページの一部へのマウント(プログレッシブ導入)から、Nuxt を使ったフルスタック SPA/SSR まで段階的にスケールできる。
  • 公式で Router・状態管理(Pinia)・ビルドツール(Vite)が揃っており、選択肢に迷いにくい。

React

  • UI = 関数(状態)。JSX で JavaScript の表現力をそのまま使ってUIを組み立てる。
  • コアはUIライブラリに徹しており、ルーティング・状態管理・データ取得などは周辺ライブラリやフレームワーク(Next.js 等)で選ぶ。
  • エコシステム・求人市場・UIコンポーネントライブラリが最大級。React Native でモバイルにも展開可能。

3. 判断軸ごとの比較

判断軸StimulusVueReact
主な描画場所サーバークライアント(SSR も可)クライアント(SSR も可)
状態管理DOM に持つリアクティブ(ref/reactive, Pinia)useState/useReducer + 外部ライブラリ
学習コスト低低〜中中
部分導入のしやすさ非常に高い高い中(可能だがやや大げさになりがち)
複雑なUIへの耐性低い(状態が増えると破綻しやすい)高い高い
公式で揃うもの最小限Router / Pinia / Vite など一式コアのみ(周辺は選択)
エコシステム規模小大最大
SEO・初期表示有利(サーバーHTML)SSR(Nuxt)で対応SSR(Next.js 等)で対応
API 設計不要(HTML を返す)JSON API が必要JSON API が必要

4. 技術ごとの「向いている/向いていない」

Stimulus が向いているケース

  • ドロップダウン、モーダル、タブ、トグル、クリップボードコピー、文字数カウンタなどの 小さな振る舞い
  • フォームの入力補助、バリデーション表示、確認ダイアログ
  • Turbo Frames / Streams と組み合わせた一覧の絞り込み・インライン編集
  • 管理画面・社内ツール・CRUD 中心のアプリ

Stimulus が向いていないケース

  • 1画面内で多数の状態が相互に依存する UI(例:複雑なフォームビルダー、ドラッグ&ドロップエディタ、表計算的な画面)
  • オフライン対応やクライアント側でのリッチなデータ操作が必要な画面
  • サイン:コントローラ間で状態を同期するコードが増えてきた、JS で HTML 文字列を組み立て始めた → Vue/React の島を検討する

Vue が向いているケース

  • Rails/Laravel/Django などの既存画面の一部をリッチ化したい(部分マウント)
  • バックエンド寄りのチームが SPA に踏み出す
  • 中規模の SPA を、公式の推奨構成で迷わず作りたい
  • テンプレートを HTML に近い形で保ちたい(デザイナーとの協業)

React が向いているケース

  • 大規模・長期運用のプロダクトで、採用や外部ライブラリの選択肢を重視する
  • Next.js などを使ったフルスタック Web アプリ、SSR/SSG を含むサイト
  • React Native とあわせたマルチプラットフォーム展開
  • 高度なUIコンポーネント(デザインシステム、ヘッドレスUI 等)を活用したい

5. 組み合わせ方のベストプラクティス

パターンA:Stimulus 単体(Hotwire 構成)

  • まずはこれで始め、本当に必要になるまでクライアント側フレームワークを入れない。
  • 1コントローラ = 1つの振る舞い。小さく汎用的に作り、HTML 側で組み合わせる。

パターンB:Stimulus + 「アイランド」としての Vue/React

  • 大半の画面は Stimulus、特定の複雑なウィジェットだけ Vue/React でマウントする。
  • 境界ルール
    • Vue/React コンポーネントのマウントは Stimulus コントローラの connect() で行い、disconnect() で必ずアンマウントする(Turbo の画面遷移でのメモリリーク防止)。
    • 初期データは data 属性(JSON)で渡し、以降の通信は JSON API で行う。
    • 1つの DOM 領域を Stimulus と Vue/React の両方が書き換えないようにする。

パターンC:Vue / React の SPA

  • バックエンドは JSON API に専念し、画面はすべてクライアントで構築。
  • SEO や初期表示が重要なら Nuxt / Next.js などの SSR フレームワークを使う。

避けたいアンチパターン

  • 同じ画面に Vue と React を混在させる(バンドルサイズ・学習コスト・保守コストが倍増)
  • Stimulus で大量の状態を JS 変数に持ち、手作業で DOM を同期する(実質的な自前フレームワーク化)
  • 「とりあえず React」で、サーバーレンダリングで十分なCRUD画面まで SPA 化する(API・認証・ルーティングの二重実装が発生)

6. 選定フローチャート

Q1. サーバーサイドで HTML を返す構成(Rails 等)か?
 ├─ Yes → Q2へ
 └─ No(API + 別フロント)→ Q4へ

Q2. 必要なのは小さな振る舞いの追加が中心か?
 ├─ Yes → Stimulus(+ Turbo)
 └─ No → Q3へ

Q3. 複雑なUIは一部の画面・ウィジェットに限られるか?
 ├─ Yes → Stimulus + Vue/React のアイランド
 └─ No(アプリ全体が複雑)→ Q4へ

Q4. 次のいずれかに当てはまるか?
    ・大規模チーム/長期運用/採用重視
    ・React Native との共有
    ・特定の React 製ライブラリが必須
 ├─ Yes → React(必要なら Next.js)
 └─ No → Vue(必要なら Nuxt)※チームの経験がある方を優先

7. 選定時のチェックリスト

  • HTML を作るのはサーバーか、クライアントか
  • 画面内の状態の数と、相互依存の複雑さ
  • チームのスキルセット(バックエンド中心か、フロント専任がいるか)
  • SEO・初期表示速度の要件
  • 将来の拡張(モバイルアプリ、マルチプラットフォーム)
  • 採用・引き継ぎのしやすさ
  • 必要なライブラリ(UIキット、エディタ、グラフ等)がその技術で揃うか
  • 既存コードベースとの整合性(1プロダクト内の技術スタックはなるべく増やさない)

8. まとめ

  • Stimulus:サーバーが主役。「HTML に少しの振る舞いを」。最小コストで最大の生産性。
  • Vue:段階的に導入できるバランス型。部分導入から SPA まで迷わず進める。
  • React:最大のエコシステムと拡張性。大規模・長期・マルチプラットフォームに強い。

迷ったら 「シンプルな方から始め、複雑さが実際に現れた箇所だけ強い道具を使う」 のが最も失敗しにくい方針です。

0件のページ