# Claude CodeにSvelte 5のRunesを正しく書かせる──let宣言・export let・$:リアクティブをCLAUDE.mdで封じる
## はじめに
Claude CodeにSvelte 5のコードを生成させると、`let count = 0`や`export let`が出てきたり`$:`リアクティブ宣言を使ったコードが生成されたりする。既存のSvelteKitルーティング記事とは別に、本記事はSvelte 5固有の「Runes APIへの移行」問題に特化する。Svelte 4では`let count = 0`がリアクティブだったため、Claude Codeが同じパターンを生成しやすい。CLAUDE.mdでルールを定義すれば最初から正しいRunesコードが生成される。
---
## Claude CodeがSvelte 5で生成しやすいパターンを正す
### `let` 宣言 → `$state()` / `$derived()`
Svelte 4では`let`がリアクティブだったが、Runesモードでは`let`変数はリアクティブにならない。`$:`での派生値も動作しない。
```svelte
```
```svelte
```
### `export let` → `$props()`
Svelte 4の`export let`でpropsを定義するパターンが生成されやすい。Svelte 5 Runesモードでは`export let`はコンパイルエラーになる。
```svelte
```
```svelte
```
### `$:` リアクティブ宣言 → `$derived()` / `$effect()`
Svelte 4の`$:`を使ったリアクティブ宣言が生成されやすい。Runesモードでは`$:`は動作しない。派生値には`$derived()`、サイドエフェクトには`$effect()`を使う。
```svelte
```
```svelte
```
---
## CLAUDE.mdとPostToolUseでSvelte 5パターンを自動担保する
`svelte.config.js`に`compilerOptions: { runes: true }`を追加してRunesモードを強制した上で、以下のCLAUDE.mdを設定する。
```markdown
## Svelte 5 Runesルール
### 状態管理
- リアクティブな状態は `$state()` で宣言する(`let count = 0` は非リアクティブ)
- 派生値は `$derived()` で宣言する
- サイドエフェクトは `$effect()` で記述する(クリーンアップはreturn関数で返す)
### Props定義
- propsは `$props()` で定義する(`export let` はRunesモードでコンパイルエラー)
- TypeScriptインターフェースで型定義する: `let { name }: Props = $props()`
- バインド可能なpropsは `$bindable()` で明示する
### 禁止事項
- `export let` 禁止(`$props()` を使う)
- `$:` リアクティブ宣言禁止(`$derived()` / `$effect()` を使う)
- Runesモードで単純な `let` による状態宣言禁止(`$state()` を使う)
```
`.svelte`ファイル編集後に`svelte-check`で型チェックを自動実行する。
```json
{
"hooks": {
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "npx svelte-check --output machine 2>&1 | head -20" }]
}]
}
}
```
---
## EM視点──Svelte 4/5混在コードベースへの対策
Svelte 5は後方互換性を持つため`runes: false`モードでSvelte 4コードも動作する。CLAUDE.mdを設定しないとSvelte 4スタイルが追加され、混在が広がる。`svelte.config.js`で`runes: true`を強制し、CLAUDE.mdで禁止パターンを明示すれば混在を防げる。Svelte 5 Runesは明示的なリアクティビティモデルにより型推論との相性も向上しており、`$props()`のTypeScriptインターフェース定義を必須化することで生成コンポーネントの型安全性が自動的に担保される。既存コードに`export let`や`$:`がないかgrepで確認するとよい。
---
## まとめ
Claude CodeがSvelte 5で踏む地雷は`let`による非リアクティブ宣言・`export let`・`$:`だ。CLAUDE.mdに本記事のテンプレートを追記して今すぐリポジトリにコミットしてほしい。svelte-checkのPostToolUseフックを合わせて設定すれば、型定義ミスもその場で自動修正される。

コメント