デザイナー、Web制作者もできるSvelte入門
■第9話:Svelteの新しい状態管理、Runes
(最終更新日:2025.05.06)

(絵が小さい場合はスマホを横に)
「状態管理を分かりやすく」
Svelte5では、状態管理の仕組みが大きく見直され、新たに「Runes(ルーン)」と呼ばれる構文が導入された。
従来の$:によるリアクティブ宣言に代わり、関数ベースでより明示的かつ構造的な状態管理が可能になる。
本記事では、Runesを使って状態管理の基本から応用までを一気に紹介する。
1.Runesの基本:状態・派生・副作用
1.1 $state — 再代入可能な状態
$stateはリアクティブな状態を定義するためのRuneだ。
以前はletで文頭で定義するだけでリアクティブな状態に出来たが、Runesを用いる場合は、$stateを使って初期値と共に定義する。
以下のように定義する。count++ のように再代入すれば、自動的にUIも更新される。
$stateによるリアクティブの定義
1.2 $derived — 派生した値の自動更新
$derivedは、他の状態から導かれる値を定義するRuneだ。
下記のように定義すると、countの値が奇数の時にisEven()がfalse、偶数の時にisEven()がtrueを示すようになる。
$derivedによる派生した値の更新
1.3 $effect — 値の変化に応じた副作用処理
$effectは副作用の処理になる。countの値が変化した際にalertを出す。
下記の場合、countが5の倍数になった際にalertを表示する。
$effectによる副作用の反映
1.4 $props — 親コンポーネントから値を受け取る
$propsを用いると、親コンポーネントから値(プロパティ)を受け取ることができる。
以前は子コンポーネントでexport letを定義して受け取っていたので、
$propsを使うことで、よりプロパティを受け取っていることが明確になる。
$propsで親コンポーネントから値を受け取る
1.5 その他のRunes
上記の4つ以外にも、双方向に値を反映できるようになる$bindable、
自コンポーネントのルートDOM要素を取得する$host、ログを出力する$inspect、
子コンポーネントから親コンポーネントへイベントを通知する$dispatchなどがある。
取り合えず、ここまで覚えておけば、一通り作りたいものは作れるはずだ。
2.高度なRunes、コンポーネント間の連携
1.5、その他のRunesで紹介した少し高度なRunesについても解説しよう。
2.1 $props と $bindable
$propsは親コンポーネントから子コンポーネントへ値を受け渡す場合に使う。
そして、$bindableは双方向バインディングさせたい場合に使う。
これにより、子から親に値を渡すこともできるようになる。
$inspect — 状態の監視
2.2 $inspectによるログ出力
$inspectを使うと、状態をconsoleで出力することができる。
使い方は以下の通りである。単純にconsole.logで出力した結果が出る。
$inspectで状態をconsole出力する
2.3 $host — DOM要素の直接操作
$hostを使うと、DOM要素を直接呼び出すことができる。
以下のように、対象のDOMのstyleを変更することができる。
$hostでDOM要素を直接操作
3.実践:カウンターアプリでRunesを体感
実際のカウンターアプリで、その様子を見てみよう。 まずは、$stateと$derivedは、他の状態から導かれる値を定義するRuneだ。 こちらは最初に説明した$stateと$derivedを用いた例になる。 count変数の変化によって、表示がcountの値と「偶数」「奇数」に変化する。
$stateと$derivedによるカウンター
これは、下記のような非常に単純なコードになる。$stateを用いてcount変数をリアクティブな状態にして、 $derivedを用いて2で割り切れるときに偶数、そうでないときに奇数と表示するようにしている。 countはincrement関数によって、ボタンを押したときに1ずつ増加し、増加した時の変化が表示に反映されるようにしている。
$stateと$derivedのリアクティブなコード
次に$bindableを用いた例を示す。$bindableは子コンポーネントの変化を親コンポーネントに反映させるときに使う。 加えて下記では、子コンポーネントの変化を子コンポーネント自体にも反映している。 inputで入力した文字が各々のコンポーネントの表示に反映されている。
$bindableによる双方向バインディング
実際のコードは下記のようになる。子コンポーネントは$propsで親からの値を受け取っている。 これを$bindableで受けることで、子コンポーネントのinputの入力値(テキスト)を変化させると、 子コンポーネントのvalue、親コンポーネントのvalue(=message)、両方を同時に変化させることができる。
子コンポーネント(上)と親コンポーネント(下)
最後に$hostの例を説明する。 こちらはDOM要素を直接呼ぶもので、このようにDOM要素のstyleを変更すると、 そのコンポーネントのstyleを変更することができる。
$hostによるstyleの変更
このコンポーネントはdecrementボタンとincrementボタンからだけでなるので、 そのコンポーネントの周りだけが青くなっているのが分かると思う。
$hostによるstyleの反映
4.注意点
Runeは関数であるため、必ず()をつけて呼び出す必要がある。 そして、$stateを使わない再代入はリアクティブにならず、ただの変数になる。 $hostに関しても必ず()を付けよう。「let el = $host」ではなく「let el = $host()」と各必要がある。
5.まとめと今後の展望
RunesによってSvelteの状態管理はより構造的で直感的になった。 副作用の分離や状態の可視性向上により、大規模開発にも適したアーキテクチャが実現可能になる。 Svelte5は昨年の10月に安定版がリリースされ、Runesの機能を如何なく発揮できる。 ReactやVueに並ぶフロントエンドの選択肢として本格的に導入できるフェーズに来ている。 新しいプロジェクトがある際には、ぜひSvelteを使ってみよう。 モダンフロントを知らないメンバーでも、比較的早く使いこなせるはずだ。
▼参考図書、サイト
Introducing runes SVELTE公式サイト
Svelte Tutorial SVELTE公式サイト