Svelte入門 - コンパイラ型UIフレームワーク実践ガイド

beginner | 60分 で読める | 2026.04.10

公式ドキュメント

この記事の要点

• Svelteのリアクティビティとコンポーネント設計
• runesによる新しいリアクティブ宣言(Svelte 5)
• ストア・条件付きレンダリング・非同期データ取得

このチュートリアルで学ぶこと

  • ✓ Svelteプロジェクトのセットアップ (Vite)
  • ✓ コンポーネントとprops
  • ✓ リアクティビティ (runes含む)
  • ✓ イベント処理と双方向バインディング
  • ✓ ストアによる状態管理
  • ✓ 条件付き / ループレンダリング

前提条件

  • HTML / CSS / JavaScript の基礎
  • Node.js 20 以上
  • npm または pnpm の使い方
  • コンポーネント指向UIの概念を少しでも知っていると理解しやすい

プロジェクトのセットアップ

# Vite + Svelte テンプレート
npm create vite@latest my-svelte-app -- --template svelte-ts

cd my-svelte-app
npm install
npm run dev

ディレクトリ構造

my-svelte-app/
├── src/
│   ├── App.svelte
│   ├── main.ts
│   ├── lib/
│   │   └── Counter.svelte
│   └── app.css
├── index.html
├── svelte.config.js
├── vite.config.ts
└── tsconfig.json

ポイント: Svelteはコンパイル時に最適化されるため、仮想DOMを使わず直接DOMを操作します。バンドルサイズが小さく高速なのが最大の強みです。

基本概念

Svelteは「実行時フレームワーク」ではなく「コンパイラ」です。 .svelte ファイルはビルド時に最適化されたVanilla JSへ変換されるため、ランタイムが非常に小さく、 起動が速く、バンドルサイズも小さくなります。Svelte 5からは runes と呼ばれる新しいリアクティビティAPIが導入されました。

.svelte → コンパイラ → 最小限のJS + DOM操作

Step 1: 最初のコンポーネント

Svelteのコンポーネントは.svelteファイルにscript、markup、styleをまとめて記述します。




こんにちは、{name}!

bind:value により input と変数が双方向で同期します。

実践メモ: Svelte 5のrunes($state, $derived, $effect)を使うと、より明示的で予測可能なリアクティビティが実現できます。新規プロジェクトではrunesの利用を推奨します。

Step 2: runesを使ったリアクティビティ (Svelte 5)





2倍: {doubled}

  • $state で宣言した値は変更を追跡される
  • $derived は依存値から算出される値
  • $effect は副作用を実行 (マウント後に走る)

Step 3: propsとコンポーネント合成




{title}

{#if description}

{description}

{/if} {@render children?.()}




  {#snippet children()}
    
  {/snippet}

Step 4: 条件とループ



ToDo リスト

{ e.preventDefault(); addTodo(); }}>
{#if todos.length === 0}

タスクがありません

{:else}
    {#each todos as todo (todo.id)}
  • toggle(todo.id)} /> {todo.text}
  • {/each}
{/if}

注意: writableストアはグローバルな状態管理に便利ですが、多用しすぎるとデータフローが追いにくくなります。コンポーネントpropsで済む場合はストアを使わないのが原則です。

Step 5: グローバルストア

// src/lib/stores/user.svelte.ts
type User = { name: string; loggedIn: boolean };

function createUserStore() {
  let state = $state<User>({ name: "", loggedIn: false });

  return {
    get value() {
      return state;
    },
    login(name: string) {
      state = { name, loggedIn: true };
    },
    logout() {
      state = { name: "", loggedIn: false };
    },
  };
}

export const userStore = createUserStore();



{#if userStore.value.loggedIn} ようこそ {userStore.value.name} さん {:else} {/if}

Step 6: 非同期データ取得





{#await promise}
  

読み込み中...

{:then posts}
    {#each posts as post}
  • {post.title}
  • {/each}
{:catch error}

{error.message}

{/await}

完成コード: ミニメモアプリ




メモ

    {#each sorted as memo (memo.id)}
  • {memo.title}

    {memo.body}

    {new Date(memo.updatedAt).toLocaleString()}
  • {/each}

よくあるエラーと対処

  1. “Cannot assign to import” エラー

    • ストアは関数でラップして getter/setter を提供する
  2. $state の再代入がUIに反映されない

    • 配列/オブジェクトは新しい参照を代入する (push だけでは検知できない場合あり)
  3. runes の使用で TypeScript エラー

    • svelte-check と @sveltejs/vite-plugin-svelte を最新に
  4. {#each} で key を指定せず DOM が崩れる

    • {#each items as item (item.id)} のように key を指定
  5. onclick で () => func(arg) ではなく func(arg) と書いて即時実行される

    • 必ず関数を渡す: onclick={() => func(arg)}

ベストプラクティス

  • runes API ($state/$derived/$effect) を積極的に使う
  • コンポーネントは小さく、責務を明確に
  • グローバル状態はストアに集約
  • $effect は本当に副作用が必要な場合のみ使用
  • CSSはコンポーネントにスコープされる特性を活かす
  • ブラウザAPIに依存するコードは onMount 相当の $effect 内で

次のステップ

  • SvelteKit (公式フルスタックフレームワーク)
  • Svelteのトランジション・アニメーション
  • TypeScriptとの深い統合
  • テスト (Vitest + @testing-library/svelte)
  • デプロイ (Vercel / Netlify / Cloudflare Pages)

まとめ

Svelteはコンパイル時に最適化を行うため、ランタイムが小さく高速です。 runes APIの導入でより明示的で予測可能なリアクティビティを手に入れ、 学習コストも低いため小〜中規模アプリに特に向いています。

FAQ

Q. Svelte 4 と Svelte 5 の違いは? A. Svelte 5 では runes ($state / $derived / $effect / $props) が導入され、 リアクティビティがより明示的になりました。既存のSvelte 4コードとも互換性がありますが、 新規開発はrunes前提で学ぶのがおすすめです。

Q. React との主な違いは? A. ReactはVirtual DOMを使うランタイム中心、Svelteはコンパイル時に最適化するコンパイラ中心です。 Svelteは .svelte という単一ファイルにHTML/CSS/JSをまとめ、記述量が少なくなる傾向にあります。

Q. SvelteKit とは? A. Next.jsに相当する公式フルスタックフレームワークです。 ルーティング、サーバ機能、SSR/SSG/SPAの切替などが統合されています。

Q. 状態管理ライブラリは必要? A. 小〜中規模ではストアパターンで十分です。大規模になる場合でも getContext / setContextrunes を使った独自ストアで十分カバーできます。

チートシート

// Svelte 5 / Vite
// https://svelte.dev/docs

$state(value)          // リアクティブな状態
$derived(expr)         // 算出値
$effect(() => {...})   // 副作用
$props()               // コンポーネントのprops
bind:value             // 双方向バインディング
on* // onclick, oninput // イベントハンドラ (Svelte 5)
{#if} {:else}          // 条件レンダリング
{#each items as item}  // ループ
{#await promise}       // 非同期レンダリング
{@render snippet()}    // スニペット呼び出し

参考リソース

補足: スタイルとトランジション

Svelteはコンポーネントの <style> が自動的にスコープされるため、 クラス名の衝突を気にせずCSSを書けます。





{#if visible}
  
フライトイン / アウト
{/if} {#if visible}
フェード
{/if}

transition: ディレクティブを使うことで、DOMが現れる / 消えるタイミングに 滑らかなアニメーションを追加できます。in: / out: を使って入退場を別々に指定することも可能です。

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る