React

SolidJSとは?Reactとの違い・Signalで速い理由・導入手順【2026年版】

SolidJSは、Reactによく似た書き味を保ちながら仮想DOMを持たないJavaScriptのUIフレームワークです。状態を「Signal」という最小単位で管理し、値が変わった箇所だけを実DOMへ直接反映するため、js-framework-benchmarkでは素のJavaScriptに迫る速度を出します。作者はReactの仮想DOMのオーバーヘッドに課題を感じたRyan Carniato。2026年7月時点の安定版は1.9系で、非同期を第一級に扱う2.0がBeta段階に入っています。この記事では、Reactとの具体的な違い、Signal・Memo・Storeの使い分け、SolidStartでの導入手順、そして「採用すべき場面/避けるべき場面」までを一気に整理します。

まとめ:SolidJSの要点と採用判断

  • 正体:Reactに似た宣言的UIを、仮想DOMなしで実現するリアクティブフレームワーク。コアは約7.6KB(min+gzip)と軽量。
  • 速い理由:Signalによるfine-grained reactivity(細粒度リアクティビティ)。コンポーネント単位ではなく、依存する箇所だけを再実行する。
  • Reactとの最大の違い:コンポーネント関数は原則1回しか実行されない。useEffectの依存配列や再レンダリング最適化に悩まされない。
  • バージョン:安定版は1.9系。2.0はBetaで、非同期(createAsync)を第一級に扱う。フルスタック開発はSolidStart 1.0以降で対応。
  • 採用判断:初期表示速度と実行時性能を最優先する小〜中規模なら有力。反対に、既製の業務向けUIライブラリや大量の採用実績を前提にするならReactが無難。

SolidJSとは:仮想DOMを持たないリアクティブフレームワーク

SolidJSは、UIの「状態」と「表示」を宣言的に結びつけるフレームワークです。ReactがJSXと宣言的UIを広めた設計思想を受け継ぎつつ、その実装手段である仮想DOMを採用していません。仮想DOMは、状態が変わるたびに仮想的なツリーを作って差分を計算し、その結果を実DOMへ反映する仕組みですが、この差分計算自体がコストになります。SolidJSはこの中間層を持たず、コンパイル時にJSXを「実DOMを直接書き換えるコード」へ変換します。

結果として、SolidJSはjs-framework-benchmarkのような公開ベンチマークで、React・Vue・Angularを上回り、素のJavaScriptに近い速度を安定して記録します。npmの週間ダウンロードは約240万、GitHubスターは約35,600と、実験段階を越えて実運用に使われる規模に達しています。

コンパイル時にJSXを実DOM操作へ変換する仕組み

SolidJSの高速さの核心は、実行時ではなくビルド時にあります。開発者が書いたJSXは、Babelプラグイン(babel-preset-solid)によって、依存関係が解析されたうえで最小限のDOM操作コードへ変換されます。仮想DOMを持つReactが「状態変化のたびにコンポーネント関数を再実行し、差分を求める」のに対し、SolidJSは「どのSignalがどのDOMノードを更新するか」をコンパイル時に確定させます。実行時に余分なツリー構築や比較が走らないため、更新コストが状態の変化量にほぼ比例します。

最小のカウンター:createSignalの動き

SolidJSの状態はcreateSignalで作ります。返り値のゲッターcount()を呼び出したJSXだけが、その値の変化を購読します。ボタンを押すと、コンポーネント全体ではなくテキストノードだけが書き換わります。

import { createSignal } from "solid-js";

function Counter() {
  const [count, setCount] = createSignal(0);
  return (
    <button onClick={() => setCount(count() + 1)}>
      Count: {count()}
    </button>
  );
}

ReactのuseStateと見た目は似ていますが、決定的に違うのはCounter関数が再実行されない点です。状態が変わっても関数本体は最初の1回きり。更新されるのはcount()を参照した箇所に限られます。

SolidJSとReactの違い:移行前に押さえる比較

「solidjs vs react」で最も知りたいのは、Reactの知識がどこまで通用し、どこで考え方を切り替える必要があるかです。構文はJSXで共通し、コンポーネント指向も同じ。一方で更新モデルは根本から異なります。

観点 SolidJS React
DOM更新 仮想DOMなし・実DOM直接更新 仮想DOMで差分計算
更新の粒度 Signal単位(該当ノードのみ) コンポーネント単位で再実行
関数の再実行 原則1回のみ 再レンダリングのたびに実行
状態 createSignal / createStore useState / useReducer
派生値 createMemo useMemo
副作用 createEffect(依存は自動追跡) useEffect(依存配列を手動指定)
コア規模 約7.6KB(min+gzip) react+react-domで約40KB前後
エコシステム 成長中・限定的 巨大・成熟

再レンダリングの考え方:依存配列からの解放

Reactでは、状態が変わるとコンポーネント関数がまるごと再実行され、useMemouseCallbackReact.memoで不要な再計算を抑える設計が求められます。SolidJSにはこの負担がありません。createEffectcreateMemoは参照したSignalを自動で追跡するため、依存配列を書く必要も、書き忘れて古い値を掴むバグもありません。ReactのuseEffect依存配列に消耗した経験があるほど、この差は大きく感じられます。

フックとの対応:createSignal・createMemo・createEffect

Reactのフックとの対応を押さえると移行が速く進みます。useStatecreateSignaluseMemocreateMemouseEffectcreateEffectに対応します。ただし呼び出す場所の制約が異なります。Reactのフックはコンポーネントのトップレベルでしか呼べませんが、SolidJSのプリミティブは条件分岐やループの外という制約はあるものの、リアクティブなスコープであればコンポーネント外でも使え、グローバルな状態をそのまま共有できます。

Signal・Memo・Storeによる状態管理

SolidJSの状態管理は3つのプリミティブで完結します。単一の値はSignal、計算結果の再利用はMemo、入れ子の大きな状態はStore、と役割で使い分けます。

createSignal:状態の最小単位

Signalはゲッターとセッターの組です。const [v, setV] = createSignal(初期値)で作り、v()で読み、setV(次の値)で更新します。読み取りがそのまま購読になるため、値を使った箇所だけが自動で更新されます。フォーム入力やトグルなど、単一の状態はこれで十分です。

createMemo:派生値のキャッシュ

ほかのSignalから計算する値はMemoにします。依存するSignalが変わったときだけ再計算し、それ以外はキャッシュを返すため、フィルタリングや集計など重い計算のUIで効きます。

import { createSignal, createMemo } from "solid-js";

const [items, setItems] = createSignal([1, 2, 3]);
const total = createMemo(() => items().reduce((a, b) => a + b, 0));

items()が変わったときだけtotalが再計算されます。同じ値を複数箇所で参照しても計算は1回で済みます。

createStore:入れ子の状態とグローバル管理

オブジェクトや配列など構造を持つ状態にはStoreを使います。createStoreはプロパティ単位でリアクティブに追跡するため、深い階層の一部だけを更新しても、変わった箇所に依存するUIだけが再描画されます。

import { createStore } from "solid-js/store";

const [state, setState] = createStore({ user: { name: "", age: 0 } });
setState("user", "age", 20);

ReactのReduxが必要とするアクションやリデューサーの定義は不要です。複数コンポーネントで共有したいときは、Storeをモジュールのトップレベルで作ってインポートするだけでグローバルストアになります。定型コードの少なさが、Reduxやその周辺ライブラリを重く感じていた開発者に響く部分です。

SolidStartでのルーティングとSSR対応

単一ページのUIを越えて、ルーティングやサーバーサイドレンダリング(SSR)を含むフルスタック開発を行うなら、公式のメタフレームワークSolidStartを使います。SolidStartは2024年5月に1.0が正式リリースされ、2026年時点では2.0のalphaが進行中です。以前案内されていたsolid-startパッケージやnpm install solid-startは非推奨で、現在の作成コマンドは次の通りです。

npm init solid@latest my-solid-app
cd my-solid-app
npm install
npm run dev

対話形式でSSRの有無やTypeScriptの利用を選ぶと、雛形が生成されます。SSRやSSGを含まない純粋なクライアント側のSolidだけが欲しい場合は、npx degit solidjs/templates/ts my-appで最小構成を取得できます。

ファイルベースルーティングと動的ルート

SolidStartのルーティングは、src/routes配下のファイル構成がそのままURLに対応します。routes/about.tsx/aboutに、routes/index.tsxはトップに割り当てられ、Next.jsのApp Routerに近い直感的な設計です。[id].tsxのように角括弧を使えば/posts/1のような動的ルートになり、パラメータはコンポーネント内で受け取れます。SSRとファイルベースルーティングが揃うため、SEOで不利になりがちなクライアントレンダリングを避けたい場面でも選択肢になります。SolidStartのレンダリング方式を検討する際は、React SEO対策で整理したSSR・SSG・プリレンダリングの使い分けが判断の下敷きになります。

UIライブラリとエコシステムの現状

「solidjs ui library」で調べる開発者が気にするのは、実案件で使えるコンポーネントが揃っているかです。2026年時点で、ヘッドレスUIのKobalte・Ark UI、それらを組み合わせたSolid UIやCorvuなど、アクセシビリティに配慮した部品が揃いつつあります。ルーティングは@solidjs/routerが公式に提供され、状態管理も本体のStoreで足ります。

ただし正直に言えば、エコシステムの層の厚さはReactに及びません。特定の業務向けデータグリッドやチャート、認証SaaSの公式SDKなどは、React版しか用意されていないことがまだあります。SolidJSを採用するかは、この「使いたい既製部品がSolidに存在するか」を先に確認してから決めるのが安全です。フレームワークの選定を俯瞰したいときは、AstroとReactの違いと使い分けや、同じ次世代フレームワークであるQwikの特徴SvelteKitとSvelteの違いと並べて比較すると位置づけが掴めます。

SolidJSが業界に与えた影響:Signalsの標準化

SolidJSを語るうえで見落とせないのが、Signalという概念そのものが主要フレームワークへ広がった事実です。SolidJSは10年以上にわたって細粒度リアクティビティを追求してきた存在で、その設計は他フレームワークの反応モデルに直接影響を与えました。

最も明確なのはAngularです。Angularは2023年5月のv16でSignalsを実験導入し、v17で安定化。そのAPIは「Solidのモデルをほぼそのまま踏襲している」と評され、Angularチームは公式にRyan Carniatoへの謝辞を述べています。PreactやVueもrefreactiveといった同系のリアクティビティを備えます。Reactだけは異なる道を選び、2025年10月7日に正式化したReact Compiler 1.0で、Signalsを取り込む代わりにメモ化を自動適用する方針を取りました。さらに、Signalsをフレームワーク非依存でJavaScript言語仕様へ入れるTC39の提案は2024年4月にStage 1へ進んでいます。

つまりSolidJSは、単なる「速いReact代替」ではなく、フロントエンド全体の状態管理の潮流を先取りした基準点です。今Angularや将来のJavaScriptで書くコードの考え方は、SolidJSが実証してきたモデルに連なっています。

SolidJSを採用すべきでない場面と判断基準

性能面の優位は明確ですが、それだけで選ぶと後悔する場面があります。次の条件に当てはまるなら、SolidJSは見送るか、限定的な採用に留めるのが現実的です。

  • 既製の業務向けUIに強く依存する:高機能なデータグリッドや管理画面テンプレート、特定SaaSの公式SDKがReact版しかないなら、移植コストが性能メリットを上回ります。
  • 大規模な採用実績と人材確保を重視する:SolidJSの経験者はReactに比べて母数が小さく、チーム拡大や引き継ぎで学習コストが顕在化します。
  • 2.0への移行時期にある:非同期を第一級に扱う2.0はBeta段階です。長期運用する新規プロジェクトは、1.9系で始めるか2.0の安定化を待つかを最初に決めておくべきです。

反対に、初期表示と実行時性能を最優先するリアルタイムダッシュボードや、Reactアプリのバンドルと再レンダリングコストに限界を感じている小〜中規模のプロジェクトでは、SolidJSの細粒度更新が効きます。判断軸は「性能で得るもの」と「エコシステムで失うもの」の天秤で、使いたい既製部品の有無が決め手になります。

よくある質問

SolidJSとReactはどちらを使うべきですか?

初期表示速度・実行時性能・軽量なバンドルを最優先し、必要なUI部品がSolidに揃うなら SolidJS が有力です。逆に、豊富な既製ライブラリや採用実績、人材の確保を重視するなら React が無難です。構文はどちらもJSXで近く、Reactの知識の大半はSolidJSでも活きます。

仮想DOMを使わないのに、なぜ高速なのですか?

状態を「Signal」という最小単位で追跡し、変化したSignalに依存する実DOMノードだけを更新するためです。仮想DOMのような差分計算の中間層がなく、コンポーネント全体の再実行も起きないため、更新コストが状態の変化量にほぼ比例します。

SolidJSの最新バージョンは?2.0はもう使えますか?

2026年7月時点の安定版は1.9系です。非同期を第一級に扱う2.0はBeta段階で、solid-js@nextで試せますが、本番運用する長期プロジェクトはまず1.9系で始めるのが安全です。変動が速いため、最新の状況は公式のリリース情報で確認してください。

SolidJSでルーティングはどう実装しますか?

公式の@solidjs/routerを使うか、フルスタックのSolidStartを採用します。SolidStartではsrc/routes配下のファイル構成がそのままURLに対応し、[id].tsxで動的ルートを定義できます。プロジェクトはnpm init solid@latestで作成します。

SolidJS向けのUIライブラリはありますか?

あります。ヘッドレスUIのKobalte・Ark UI、それらを使ったSolid UIやCorvuなどが利用できます。ただしReactほど層は厚くないため、使いたい部品がSolidに存在するかを事前に確認することをおすすめします。

関連記事

資料請求

RELATED POSTS 関連記事