Svelte 4のstoreを書き続けるClaude Codeを止める──CLAUDE.md + Skills設定でSvelteKit開発を加速する完全ガイド

はじめに

Claude CodeにSvelteKitのコンポーネントを書かせると、export let$:記法が出てくることがある。Svelte 4の記法だ。2024年にSvelte 5がリリースされてrunes($state$derived$effect)が導入されたが、学習データの影響で旧パターンが優先されやすい。CLAUDE.mdに明示しなければ、このミスマッチが続く。


Claude CodeがSvelteKit開発でよく間違えるパターン

Svelte 4の旧記法(export let・$:)を生成する

 
 

+page.tsと+page.server.tsの混同

DB接続や秘密キーを扱うコードが+page.ts(クライアントでも動く)に入ると、シークレットが漏れる。

// ❌ +page.ts にDB接続(クライアントにも渡る)
import { db } from '$lib/server/db'; // buildエラー

// ✅ +page.server.ts(サーバーのみで実行)
import { db } from '$lib/server/db';
export const load = async () => {
  return { users: await db.query.users.findMany() };
};

form actionsの型定義省略

form actionsはSvelteKitが型を自動生成するが、Claude Codeがimportを省略することがある。

// ✅ 型安全なform actions(+page.server.ts)
import type { Actions, PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ locals }) => {
  return { user: locals.user };
};

export const actions: Actions = {
  create: async ({ request, locals }) => {
    const data = await request.formData();
    await db.insert(todos).values({ title: data.get('title') as string });
    return { success: true };
  }
};

CLAUDE.mdでSvelte 5 runesを正しく指示する

# SvelteKit プロジェクト

技術スタック

SvelteKit 2 + Svelte 5 + TypeScript strict / Tailwind CSS v4 / Drizzle ORM + PostgreSQL

状態管理(Svelte 5 runes)

  • $state: リアクティブ変数(export letは使わない)
  • $derived: 計算値($:記法は使わない)
  • $effect: 副作用($:ブロックは使わない)
  • グローバル状態: .svelte.tsファイルで$stateを使う(サーバー側では使用禁止)
  • ファイルの役割分離

  • DB・認証・秘密キー → +page.server.tsのみ
  • 外部公開APIのfetch → +page.ts(必要な場合のみ)
  • 型は ./$types から必ずimportする(PageServerLoad・Actions・PageProps)
  • データ取得・更新

  • データ取得: load関数(+page.server.ts)
  • ミューテーション: form actions(JSなしでも動くことを前提に設計)
  • APIルート(/api/): Webhook・外部連携のみ
  • Svelte最新仕様参照

  • コード生成前に https://svelte.dev/docs/svelte/llms.txt を参照すること
  • SSR注意

  • モジュールレベルの$stateをサーバー側のグローバル状態に使わない(リクエスト間リーク)
  • サーバー側のリクエスト固有データはload関数のreturnかcontextAPIで渡す
  • SvelteはLLM向けにllms.txtを公式公開している(svelte.dev/docs/svelte/llms.txt)。CLAUDE.mdにURLを書いておくと、Svelte 5 runesを含む最新仕様を参照した上でコードを生成してくれる。

    コミュニティ製のSkillsも公開されている。claude-skills/sveltekit-svelte5-tailwind-skill(SvelteKit 2 + Svelte 5 + Tailwind v4統合)やsplinesreticulating/claude-svelte5-skill(SvelteKit全般)がコミュニティから報告されているが、公式確認は取れていないため導入時はリポジトリの最新状況を確認してほしい。


    PostToolUseフック──Svelte・TypeScriptのフォーマット自動化

    .svelteファイルへの書き込み時にprettierを自動実行する設定だ。

    {
      "hooks": {
        "PostToolUse": [
          {
            "matcher": "Write|Edit",
            "hooks": [{ "type": "command", "command": "bash .claude/hooks/svelte_format.sh" }]
          }
        ]
      }
    }
    #!/usr/bin/env bash
    FILE_PATH=$(python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('tool_input', {}).get('file_path', ''))")
    if [[ "$FILE_PATH" == *.svelte ]] || [[ "$FILE_PATH" == *.ts ]]; then
        npx prettier --write "$FILE_PATH" 2>/dev/null || true
    fi

    型チェックはStopフックで実行する。

    "Stop": [{ "hooks": [{ "type": "command", "command": "npx svelte-check --tsconfig ./tsconfig.json 2>&1 | tail -5" }] }]

    EM視点──Next.jsとの使い分けとCLAUDE.md標準化

    SvelteKitとNext.jsの選び方はシンプルだ。SvelteKitはコンパイル時最適化でランタイム不要、form actionsでProgressive Enhancementもデフォルト対応しており、小〜中規模でシンプルさを優先するプロジェクトとの相性がいい。Reactエコシステムを活かしたいチームや大規模プロジェクトはNext.jsを選ぶことになる。

    CLAUDE.mdをリポジトリにコミットすることで、チーム全員が同じルールでClaude Codeを使える。export let$:を禁止パターンとして明記しておけば、コードレビューで旧記法を指摘する機会が減る。新メンバーが「Svelte 5 runesとは何か」を独自調査する手間も省ける。


    まとめ

    export let$:が出てくる根本原因は、Svelte 5 runesのルールをCLAUDE.mdで伝えていないことだ。「$state$derived$effectを使う」「export let$:は使わない」の2行を追記し、svelte.dev/docs/svelte/llms.txtの参照URLも加えてほしい。それだけで次のセッションから変わる。

    コメント

    タイトルとURLをコピーしました