jpskill.com
🛠️ 開発・MCP コミュニティ

svelte

Svelte 5とSvelteKit 2のエキスパートとして、ラン、スニペット、ストアなどを活用し、仮想DOMなしで最小限のJavaScriptにコンパイルしてWebアプリ開発を支援するSkill。

📜 元の英語説明(参考)

You are an expert in Svelte 5 and SvelteKit 2. You help developers build web applications using runes ($state, $derived, $effect, $props, $bindable, $inspect), snippets, stores, transitions, and actions — compiling to minimal vanilla JavaScript with no virtual DOM. Use when building Svelte apps, migrating from Svelte 4, or working with SvelteKit.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Svelte 5とSvelteKit 2のエキスパートとして、ラン、スニペット、ストアなどを活用し、仮想DOMなしで最小限のJavaScriptにコンパイルしてWebアプリ開発を支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o svelte.zip https://jpskill.com/download/15434.zip && unzip -o svelte.zip && rm svelte.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15434.zip -OutFile "$d\svelte.zip"; Expand-Archive "$d\svelte.zip" -DestinationPath $d -Force; ri "$d\svelte.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して svelte.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → svelte フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Svelte — コンパイル時リアクティブ UI フレームワーク

概要

Svelte は、ランタイムからコンパイル時に処理を移行し、仮想 DOM を持たない最小限のプレーンな JavaScript を生成します。Svelte 5 では、$: 宣言やストアに代わる、明示的なリアクティビティプリミティブである runes が導入されました。SvelteKit 2 は、SSR、ルーティング、およびデプロイメントアダプターを提供します。

手順

Runes リファレンス

$state — リアクティブな状態 (デフォルトではディープ):

<script lang="ts">
  let count = $state(0);
  let user = $state({ name: "Alice", age: 30 });
  user.age++;  // ディープリアクティビティ — 更新をトリガー
</script>

$state.raw — シャローリアクティブ (トリガーするには再代入が必要):

<script>
  let items = $state.raw([1, 2, 3]);
  items = [...items, 4];  // 再代入が必要
</script>

$state.snapshot — プレーンな非リアクティブコピー:

<script>
  let form = $state({ name: "", email: "" });
  const data = $state.snapshot(form);  // API 呼び出し用のプレーンなオブジェクト
</script>

$derived および $derived.by — 算出値:

<script>
  let price = $state(100);
  let quantity = $state(3);
  let total = $derived(price * quantity);

  let summary = $derived.by(() => {
    const t = items.reduce((sum, i) => sum + i.price, 0);
    return { total: t, count: items.length, avg: t / items.length };
  });
</script>

$effect — クリーンアップ付きの副作用:

<script>
  let query = $state("");
  $effect(() => {
    if (!query) return;
    const controller = new AbortController();
    fetch(`/api/search?q=${query}`, { signal: controller.signal })
      .then(r => r.json()).then(data => { results = data; });
    return () => controller.abort();
  });
</script>

$props — コンポーネントの props:

<script>
  let { label, variant = "primary", onclick, class: className = "", ...rest } = $props();
</script>
<button class="btn btn-{variant} {className}" {onclick} {...rest}>{label}</button>

$bindable — 双方向バインディング:

<!-- Input.svelte -->
<script>
  let { value = $bindable(""), placeholder = "" } = $props();
</script>
<input bind:value {placeholder} />

$inspect — リアクティブな値のデバッグ (開発時のみ):

<script>
  $inspect(count, doubled);
  $inspect(count).with((type, value) => console.log(`[${type}]`, value));
</script>

スニペット (スロットの置き換え)

Svelte 5 では、スロットが型付きの再利用可能なマークアップフラグメントに置き換えられました。

<!-- List.svelte -->
<script>
  let { items, row, children } = $props();
</script>
<ul>
  {#each items as item}
    <li>{@render row(item)}</li>
  {/each}
</ul>
{@render children?.()}
<!-- Parent.svelte -->
<List {items}>
  {#snippet row(item)}
    <strong>{item.name}</strong> — {item.description}
  {/snippet}
</List>

ストア (共有状態)

// stores/cart.ts — 書き込み可能なストア (Svelte 4 スタイル、まだ動作します)
import { writable, derived } from "svelte/store";

export const cart = writable<CartItem[]>([]);
export const cartTotal = derived(cart, ($cart) =>
  $cart.reduce((sum, item) => sum + item.price * item.quantity, 0)
);

Svelte 5 の代替.svelte.ts モジュールでの $state:

// state/counter.svelte.ts
let count = $state(0);
let doubled = $derived(count * 2);

export function getCounter() {
  return {
    get count() { return count; },
    get doubled() { return doubled; },
    increment() { count++; },
  };
}

トランジション

<script>
  import { fade, fly, slide } from "svelte/transition";
  import { flip } from "svelte/animate";
  let items = $state(["Apple", "Banana"]);
</script>
{#each items as item (item)}
  <div animate:flip={{ duration: 300 }} transition:fade>{item}</div>
{/each}

Svelte 4 からの移行

Svelte 4 Svelte 5
let count = 0 let count = $state(0)
$: doubled = count * 2 let doubled = $derived(count * 2)
$: { sideEffect() } $effect(() => { sideEffect() })
export let prop let { prop } = $props()
<slot /> {@render children()}
<slot name="header" /> {@render header?.()}
Svelte stores .svelte.ts ファイルでの $state

SvelteKit 2

<!-- +page.svelte -->
<script>
  let { data } = $props();  // +page.ts の load 関数から
</script>
<h1>{data.title}</h1>
npx sv create my-app          # SvelteKit プロジェクト
npm create vite@latest -- --template svelte-ts  # スタンドアロン Svelte

例 1: ストアを使用したショッピングカート

<!-- CartSummary.svelte -->
<script lang="ts">
  import { cart, cartTotal, removeFromCart } from "$lib/stores/cart";
</script>
<div class="cart">
  {#each $cart as item (item.id)}
    <div>{item.name} x {item.quantity} — ${(item.price * item.quantity).toFixed(2)}
      <button onclick={() => removeFromCart(item.id)}>Remove</button>
    </div>
  {/each}
  <p>Total: ${$cartTotal.toFixed(2)}</p>
</div>

例 2: $effect を使用した非同期データフェッチ

<script>
  let userId = $state(1);
  let user = $state(null);
  let loading = $state(false);

  $effect(() => {
    loading = true;
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(data => { user = data; loading = false; });
  });
</script>
{#if loading}<p>Loading...</p>
{:else if user}<p>{user.name}</p>{/if}

ガイドライン

  1. 状態のための Runes — Svelte 5 では $state()$derived()$effect() を使用します。Svelte 4 の $: 構文よりもクリーンです。
  2. スコープ付きスタイル<style> の CSS はコンポーネントスコープです。CSS モジュールは不要です。
  3. ストア vs runes — 新しいコードには .svelte.ts$state を使用します。書き込み可能/派生ストアはまだ動作します。
  4. 組み込みのトランジションtransition:fadetransition:fly を使用します。アニメーションライブラリは不要です。
  5. 小さなバンドル — Svelte はコンパイルされます。一般的なアプリのサイズは 5〜10KB で、React の 40KB 以上と比較して小さくなります。
  6. フルスタックのための SvelteKit — SSR、ルーティング、API エンドポイント、デプロイメントアダプター
  7. TypeScript — 型安全なコンポーネントには <script lang="ts"> を使用します。
  8. DOM のためのアクション — `use:a
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Svelte — Compile-Time Reactive UI Framework

Overview

Svelte shifts work from runtime to compile time, producing minimal vanilla JavaScript with no virtual DOM. Svelte 5 introduces runes — explicit reactivity primitives that replace $: declarations and stores. SvelteKit 2 provides SSR, routing, and deployment adapters.

Instructions

Runes Reference

$state — reactive state (deep by default):

<script lang="ts">
  let count = $state(0);
  let user = $state({ name: "Alice", age: 30 });
  user.age++;  // deep reactivity — triggers updates
</script>

$state.raw — shallow reactive (must reassign to trigger):

<script>
  let items = $state.raw([1, 2, 3]);
  items = [...items, 4];  // must reassign
</script>

$state.snapshot — plain non-reactive copy:

<script>
  let form = $state({ name: "", email: "" });
  const data = $state.snapshot(form);  // plain object for API calls
</script>

$derived and $derived.by — computed values:

<script>
  let price = $state(100);
  let quantity = $state(3);
  let total = $derived(price * quantity);

  let summary = $derived.by(() => {
    const t = items.reduce((sum, i) => sum + i.price, 0);
    return { total: t, count: items.length, avg: t / items.length };
  });
</script>

$effect — side effects with cleanup:

<script>
  let query = $state("");
  $effect(() => {
    if (!query) return;
    const controller = new AbortController();
    fetch(`/api/search?q=${query}`, { signal: controller.signal })
      .then(r => r.json()).then(data => { results = data; });
    return () => controller.abort();
  });
</script>

$props — component props:

<script>
  let { label, variant = "primary", onclick, class: className = "", ...rest } = $props();
</script>
<button class="btn btn-{variant} {className}" {onclick} {...rest}>{label}</button>

$bindable — two-way binding:

<!-- Input.svelte -->
<script>
  let { value = $bindable(""), placeholder = "" } = $props();
</script>
<input bind:value {placeholder} />

$inspect — debug reactive values (dev only):

<script>
  $inspect(count, doubled);
  $inspect(count).with((type, value) => console.log(`[${type}]`, value));
</script>

Snippets (Replacing Slots)

Svelte 5 replaces slots with typed, reusable markup fragments:

<!-- List.svelte -->
<script>
  let { items, row, children } = $props();
</script>
<ul>
  {#each items as item}
    <li>{@render row(item)}</li>
  {/each}
</ul>
{@render children?.()}
<!-- Parent.svelte -->
<List {items}>
  {#snippet row(item)}
    <strong>{item.name}</strong> — {item.description}
  {/snippet}
</List>

Stores (Shared State)

// stores/cart.ts — Writable store (Svelte 4 style, still works)
import { writable, derived } from "svelte/store";

export const cart = writable<CartItem[]>([]);
export const cartTotal = derived(cart, ($cart) =>
  $cart.reduce((sum, item) => sum + item.price * item.quantity, 0)
);

Svelte 5 alternative$state in .svelte.ts modules:

// state/counter.svelte.ts
let count = $state(0);
let doubled = $derived(count * 2);

export function getCounter() {
  return {
    get count() { return count; },
    get doubled() { return doubled; },
    increment() { count++; },
  };
}

Transitions

<script>
  import { fade, fly, slide } from "svelte/transition";
  import { flip } from "svelte/animate";
  let items = $state(["Apple", "Banana"]);
</script>
{#each items as item (item)}
  <div animate:flip={{ duration: 300 }} transition:fade>{item}</div>
{/each}

Migration from Svelte 4

Svelte 4 Svelte 5
let count = 0 let count = $state(0)
$: doubled = count * 2 let doubled = $derived(count * 2)
$: { sideEffect() } $effect(() => { sideEffect() })
export let prop let { prop } = $props()
<slot /> {@render children()}
<slot name="header" /> {@render header?.()}
Svelte stores $state in .svelte.ts files

SvelteKit 2

<!-- +page.svelte -->
<script>
  let { data } = $props();  // from +page.ts load function
</script>
<h1>{data.title}</h1>
npx sv create my-app          # SvelteKit project
npm create vite@latest -- --template svelte-ts  # standalone Svelte

Examples

Example 1: Shopping cart with stores

<!-- CartSummary.svelte -->
<script lang="ts">
  import { cart, cartTotal, removeFromCart } from "$lib/stores/cart";
</script>
<div class="cart">
  {#each $cart as item (item.id)}
    <div>{item.name} x {item.quantity} — ${(item.price * item.quantity).toFixed(2)}
      <button onclick={() => removeFromCart(item.id)}>Remove</button>
    </div>
  {/each}
  <p>Total: ${$cartTotal.toFixed(2)}</p>
</div>

Example 2: Async data fetching with $effect

<script>
  let userId = $state(1);
  let user = $state(null);
  let loading = $state(false);

  $effect(() => {
    loading = true;
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(data => { user = data; loading = false; });
  });
</script>
{#if loading}<p>Loading...</p>
{:else if user}<p>{user.name}</p>{/if}

Guidelines

  1. Runes for state — Use $state(), $derived(), $effect() in Svelte 5; cleaner than Svelte 4's $: syntax
  2. Scoped styles — CSS in <style> is component-scoped; no CSS modules needed
  3. Stores vs runes — Use $state in .svelte.ts for new code; writable/derived stores still work
  4. Transitions built-in — Use transition:fade, transition:fly; no animation library needed
  5. Small bundles — Svelte compiles away; typical app ships 5-10KB vs 40KB+ for React
  6. SvelteKit for full-stack — SSR, routing, API endpoints, deployment adapters
  7. TypeScript — Use <script lang="ts"> for type-safe components
  8. Actions for DOM — Use use:action for reusable DOM behavior (click-outside, tooltip)