SvelteKitを選ぶ前に知ること
SvelteKitは、Svelteの画面に、ルーティング、データ取得、フォーム処理、サーバーレンダリングを組み合わせるフレームワークです。静的なページだけでなく、ログインやフォーム送信を持つWebアプリも一つのプロジェクトで扱えます。
2025年にSvelteKitを評価するときの中心は、ベンチマーク順位ではありません。状態管理をチームが理解できるか、サーバー処理をどこへ置くか、SSRや静的生成を選べるか、既存資産と合うかを確認します。
Svelteはコンポーネントをビルド時にコンパイルします。そのため、Reactのような仮想DOMを前提とする設計とは考え方が異なります。ただし、コンパイルするから常に高速という意味ではありません。画像、データ取得、画面の状態、配信先で利用者の体験は変わります。
この記事では、安定した基礎としてSvelte 5のRunesとSvelteKitのload、form actions、SSRを扱います。Svelteの基本構文から始めたい場合は、Svelte入門を先に読むと理解しやすくなります。
Svelte 5 Runesの役割
Runesは、Svelte 5で導入されたリアクティビティの仕組みです。$stateで状態、$derivedで状態から計算する値、$effectでDOM操作や分析ログなどの副作用を明示します。Svelte 5ではこれらを使う書き方が安定した基本です。
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
function increment() {
count += 1;
}
</script>
<button onclick={increment}>+1</button>
<p>{count} の2倍は {doubled}</p>
countが変わると、doubledも必要なときに再計算されます。doubledを更新するためだけの副作用を書く必要はありません。この区別が、Runesを使うときの重要なポイントです。
| Rune | 役割 | 主な用途 |
|---|---|---|
$state | 変更される状態を宣言する | 入力値、選択状態、表示の切り替え |
$derived | 他の状態から値を計算する | 合計、フィルター済み一覧、表示用の文言 |
$effect | 状態変更に応じて副作用を実行する | DOM API、分析、外部ライブラリ連携 |
$props | 親から渡されるpropsを受け取る | ページのdata、再利用部品の入力 |
$effectを計算用に使わない
$effectは便利ですが、派生値を代入するための道具ではありません。例えばtotal = price * quantityを$effectで更新すると、依存関係と更新順を考える必要が増えます。その場合は$derived(price * quantity)にします。
$effectが向くのは、Canvasへの描画、ブラウザAPI、外部UIライブラリの初期化、分析イベントの送信など、Svelteの画面更新以外へ影響を出す処理です。副作用内で状態を更新し続けると、ループや追跡しづらい挙動になるため、必要性を確認します。
既存のSvelte 4コードとの関係
Svelte 5は既存の書き方をすべて一度に捨てるための製品ではありません。ただし、新規コードでRunesを採用するなら、$:による派生値や旧来のprops記法と混在させる範囲をチームで決めます。移行では自動変換の結果をそのまま信頼せず、フォーム、非同期処理、状態共有のテストをします。
Runesは状態管理ライブラリそのものではありません。画面をまたぐ状態を何に置くか、URLで表せる状態か、サーバーを正とするデータかは、従来どおり設計する必要があります。検索条件ならURL、ログイン状態ならサーバーセッション、短いUI状態ならコンポーネント内の$stateが候補になります。
SvelteKitのloadでデータを読む
SvelteKitでは、ルートごとのload関数でページに必要なデータを準備します。サーバー専用のデータベースや秘密情報へ触れる場合は、+page.server.tsまたは+layout.server.tsに置きます。
// src/routes/articles/+page.server.ts
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals }) => {
const articles = await locals.articleRepository.listPublished();
return { articles };
};
ページ側では、loadが返した値をdataとして受け取れます。
<script lang="ts">
let { data } = $props();
</script>
<h1>記事一覧</h1>
{#each data.articles as article}
<a href={`/articles/${article.slug}`}>{article.title}</a>
{/each}
サーバーloadが返す値は、ブラウザへ渡せる形でなければなりません。DB接続、秘密鍵、認可用の内部オブジェクトを返さず、画面に必要な値だけを選びます。認可は「一覧を返す前」にサーバーで行い、画面側の非表示だけに依存しません。
loadの責任を小さくする
loadへ複数画面分のデータを集めすぎると、遷移のたびに不要な取得や権限確認が発生します。layoutで全ページに必要な利用者情報を用意し、page loadでページ固有のデータを取る、といった分け方を検討します。
また、ページ表示に必要なデータと、クリック後に初めて必要なデータを区別します。後者まで最初のloadで取得すると、初期表示の待ち時間と返却データが増えます。キャッシュや並列取得を足す前に、どのデータがいつ必要かを整理します。
form actionsで書き込みを扱う
SvelteKitのform actionsは、ページに対するPOST処理を+page.server.tsで定義する仕組みです。通常のHTML formとして動くため、JavaScriptが使えない環境でも送信でき、必要ならuse:enhanceで画面の更新を補助できます。
// src/routes/contact/+page.server.ts
import { fail } from '@sveltejs/kit';
import type { Actions } from './$types';
export const actions: Actions = {
default: async ({ request, locals }) => {
const formData = await request.formData();
const message = formData.get('message')?.toString().trim();
if (!message) {
return fail(400, { message, error: '本文を入力してください。' });
}
await locals.contactRepository.create({ message });
return { success: true };
},
};
<script lang="ts">
let { form } = $props();
</script>
<form method="POST">
<label>
お問い合わせ内容
<textarea name="message"></textarea>
</label>
{#if form?.error}<p>{form.error}</p>{/if}
<button>送信</button>
</form>
ブラウザはフォームを送信して結果ページを受け取ります。use:enhanceは、成功後に入力欄を消す、送信中表示を出す、部分更新が必要な場合に追加します。先に通常のformでバリデーション、認可、失敗時の表示を完成させます。
通常のform POSTは、既定のcsrf.checkOriginでOrigin検査されます。ただし、これは認可・入力検証・XSS対策の代わりではありません。設定を変更する場合も、送信者、入力形式、重複送信、外部副作用の失敗時をサーバー側で設計します。送信値を戻すときは、エスケープと個人情報を確認します。
SSR・静的生成・CSRを画面ごとに選ぶ
SvelteKitはadapterとページ設定により、静的生成、サーバーレンダリング、クライアント側の動作を組み合わせられます。全ページを同じ方式に固定するのではなく、データの更新頻度、個人化、検索流入、ホスティング要件で選びます。
| 方式 | 向く画面 | 注意点 |
|---|---|---|
| 静的生成 | 公開記事、FAQ、紹介ページ | 更新時に再ビルドまたは再生成が必要 |
| SSR | ログイン状態やリクエストごとに変わる画面 | サーバー運用とキャッシュ設計が必要 |
| CSR中心 | ブラウザ内の操作が中心の画面 | 初期表示、SEO、エラー状態を別途確認する |
SSRを使えば常に正しいわけではありません。公開記事まで毎回サーバーで生成すると、キャッシュできる内容に運用コストを払うことがあります。反対に、利用者ごとの権限や在庫のようにリクエスト時点の値が必要なら、静的ページへ無理に埋め込むよりSSRやサーバーAPIを選びます。
SvelteKitのSSRは、最初のHTMLを作るための仕組みであり、認可の代わりではありません。サーバーloadやactionでデータを返すときは、本人が読める値だけを返します。レンダリング方式を決める前に、SSRが必要かを考えるで要求を整理すると安全です。
stableとexperimentalを分けて扱う
Svelte 5のRunes、SvelteKitのserver load、form actions、SSRは、日常の実装で基礎にできる機能です。一方、リリース直後の非同期UI、データ取得の新しい抽象化、低レベルな並行処理APIなどは、バージョンや安定性ラベルを公式ドキュメントで確認する必要があります。
実験的またはpreview扱いの機能は、検証用ブランチや限定画面で試せます。しかし、認証、決済、主要導線の土台に置く前には、次を確認します。
- 使用するSvelte/SvelteKitのバージョンでstableかexperimentalか
- API名・設定・エラー形式が更新で変わった場合に追随できるか
- 代替手段へ戻す範囲と、テストケースを用意できるか
- チーム全員が公式ドキュメントと変更履歴を追えるか
「新しい書き方だから」では採用理由になりません。安定機能で要件を満たせるなら、まずは安定機能を選ぶ方が、学習・レビュー・障害対応の負担を抑えられます。
SvelteKitが向く場面と注意が必要な場面
SvelteKitが向くのは、次のようなケースです。
- コンテンツページと、検索・フォーム・ログインなどの動的機能を一つのプロジェクトで管理したい
- HTML formを基礎にし、必要な画面だけを段階的に強化したい
- Svelteのコンポーネント記法とRunesをチームで統一できる
- 静的生成とSSRを、ルートごとに使い分けたい
- 既存のフレームワーク資産に強く縛られていない
注意が必要なのは、次のようなケースです。
- チームがReactやVueの大きな設計資産・部品群・運用手順をすでに持つ
- 多数の画面が同じ複雑なクライアント状態を共有し、独自の状態管理規約が必要になる
- 必要なUI部品、採用人材、外部ベンダーが別エコシステムへ強く依存している
- 既存アプリを全面移行しなければ価値を出せない計画になっている
後者でもSvelteKitが不可能なわけではありません。問題は言語機能ではなく、移行・教育・テスト・採用を含む総コストです。小さな問い合わせフォームや公開領域から導入し、チームの開発速度と運用のしやすさを確かめます。
他フレームワークとの比較は要件から始める
React、Vue、Svelteのどれが優れているかを、一般的な性能表だけで決めることはできません。比較では、次の観点を同じ重さで見ます。
| 観点 | 確認すること |
|---|---|
| 既存資産 | 再利用する部品、テスト、デザインシステムはあるか |
| チーム | レビュー、障害対応、採用を継続できるか |
| レンダリング | 静的、SSR、個人化、更新頻度の要件は何か |
| データ | 認可、フォーム、DB、外部APIの責任をどこへ置くか |
| 運用 | adapter、環境変数、監視、ロールバックを管理できるか |
SvelteKitは、Svelteの記法でフルスタックの境界を作りたいチームにとって一貫した選択肢です。Reactの既存資産を最大限使いたいならReact系の構成、Vueのチーム規約を活かしたいならVue系の構成も自然です。フレームワークを変える前に、解決したい問題が本当にレンダリングや状態管理の問題かを確かめます。
小さく選定するためのチェックリスト
- 公開ページ、ログイン画面、フォームなど代表的な三画面を選ぶ
- 画面ごとに静的生成、SSR、CSR中心のどれが必要か記録する
$state、$derived、$effectを使う場所と理由をレビューする- server loadとform actionで、認可・入力検証・失敗時の表示を実装する
- adapterを含む本番に近い環境で、Cookie、環境変数、エラー監視を確認する
- 初期表示、フォーム送信、キーボード操作、ネットワーク失敗を実機でテストする
性能は、自分たちの代表画面で測ります。画面サイズ、画像、認証、外部API、利用者の端末を含めずに得た数値は、採用後の体験を保証しません。実装時間、テストの書きやすさ、障害時の調査時間も記録して比較します。
まとめ
SvelteKitは、Svelte 5のRunesで画面状態を明示しながら、load、form actions、SSRを同じルーティング構造で扱えるフレームワークです。Runesは状態と派生値を整理し、SvelteKitのサーバー機能はデータ取得と書き込みの境界を作ります。
選定では、コンパイル方式やベンチマーク順位より、チームが状態・認可・レンダリング方式を一貫して運用できるかを見ます。まずは小さな画面で静的生成、SSR、form actionを試し、既存の技術資産と比べてから対象を広げてください。
関連記事・参考リソース
- Svelte入門
- Svelte 5 Runesの解説
- SSRが必要かを考える
- Svelte 公式ドキュメント
- SvelteKit 公式ドキュメント
- SvelteKit: Loading data
- SvelteKit: Form actions