svelte について
コンポーネント、リアクティビティ、ライフサイクル、UI構成を扱う、プロジェクト固有のSvelte 5開発ガイドです。対象ワークスペースの開発者向けで、動作に関わる変更では上流資料の確認を重視します。
主な機能
- 01Svelte 5のrunesとリアクティビティの指針
- 02コンポーネントのプロパティ、スニペット、イベントのパターン
- 03ライフサイクルと非同期リソースのパターン
- 04リアクティブなコレクションとストア連携の指針
- 05TanStack Queryのmutation規約
- 06上流ソースの確認指針
活用シーン
- 01Svelteコンポーネントの実装や更新
- 02状態管理とライフサイクルパターンの選択
- 03ワークスペースデータとリアクティブUIの接続
- 04動作に関わるSvelte API変更の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ epicenterhq/ epicenter --skill svelteインストール後、Claude Code で/svelteを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/component-ui-patterns.mdinput-ownership.mdlifecycle-and-reactivity.mdmutations-and-workspace-inputs.md詳細
Svelte のガイドライン
最初の段階では、Svelte のルーン、コンポーネントのライフサイクル、ワークスペースを基盤とする状態管理、TanStack Query の使用、ローカル UI の構成に焦点を当てます。
参照リポジトリ
- Svelte:ルーンと細粒度のリアクティビティを備えた Svelte 5 フレームワーク
- shadcn-svelte:Bits UI のプリミティブを使用した、Svelte 向け shadcn/ui の移植版
- shadcn-svelte-extras:shadcn-svelte 用の追加コンポーネント
ソースの確認
- プロパティの所有権、
bind:API、またはchildrenスニペットの型付けルールを変更する前に、Svelte$props、$bindable、およびスニペットを確認してください。 - キー付きリソースや非同期の準備完了に関するガイダンスを変更する前に、Svelte
{#key}、{#await}、およびライフサイクルフックを確認してください。 - 再利用可能な DOM の動作、アクション、またはアタッチメントに関するガイダンスを変更する前に、Svelte
{@attach}、use:、およびsvelte/attachmentsを確認してください。 SvelteMap、SvelteSet、またはリアクティブなコレクションに関するガイダンスを変更する前に、Sveltesvelte/reactivityを確認してください。- レガシー API の回避、イベント構文、スロットの移行、またはコールバックプロパティに関するガイダンスを変更する前に、Svelte 5 移行ガイドを確認してください。
- ミューテーションのライフサイクルに関するガイダンスを変更する前に、TanStack Svelte Query
createMutationと、ローカルにインストールされた型を確認してください。
上流の情報に基づく確認
Svelte 5 のルーン、コンパイラーの動作、ライフサイクル、リアクティビティ、スニペット、またはテンプレートの動作が正確性に影響する場合は、記憶だけに頼らず、ソースに基づいて確認してください。DeepWiki MCP を利用できる場合は、sveltejs/svelte を対象に絞った質問をしてください。SvelteKit との統合については sveltejs/kit、shadcn-svelte または extras のコンポーネント API については huntabyte/shadcn-svelte または ieedan/svelte-svelte-extras を対象に質問してください。DeepWiki を利用できない場合、またはリポジトリがインデックス化されていない場合は、上流のソースまたは公式ドキュメントを直接参照してください。DeepWiki は概要をつかむために使い、判断を左右する詳細は、コードを変更する前にローカルにインストールされた型、ソース、または公式ドキュメントで確認してください。
安定した基本事項や、ここまたは参照資料にすでに記載されているリポジトリ内のパターンについては、DeepWiki の使用を省略してください。
関連スキル
query-layer:TanStack Query との統合error-handling:操作の間は Result を引き継ぎ、操作の境界で結果を提示します。タグ付きエラーと$lib/reportを含みますstyling:フレックス列のスクロールに関する落とし穴を含む、CSS と Tailwind の規約ui-design:ビジュアルの方向性に加え、読み込み中、空の状態、処理待ち、ツールチップ、コンポーネント選択のパターン
Svelte 5 の基本方針
- コンポーネント内で値を直接変更する場合は、リアクティブな値に
$stateを使用します。値全体を再代入する場合に限り、$state.rawを使用します(大きな配列、置き換えのみの永続化ストア、不透明なハンドルなど)。参照をそのまま保存し、深いプロキシを作成せず、値を凍結しません。また、再代入に対してのみリアクティブに動作するため、プロパティを直接書き換えてもオブジェクトは変更されますが、リアクティビティも永続化も発生しません(エラーではありませんが、リアクティブでもありません)。深いプロキシによるリアクティビティを使わない場合や、値の同一性を保つことが重要な場合(たとえば、値を JSON にシリアライズしたり、参照で比較したりするストア)に使用します。例:packages/svelteのcreatePersistedState。 - 計算状態には
$derivedを優先します。$effectは、DOM 連携、分析、サブスクリプション、外部システムのためのブラウザー専用の例外的な手段として扱います。返されたクリーンアップ関数は、エフェクトが再実行される前と、コンポーネントが破棄されるときに実行されます。 - プロパティは変更される可能性があります。変化する値は
$derivedで計算するか、使用する箇所でプロパティを直接読み取ります。そのコンポーネントインスタンスの所有者が固定されている場合に限り、アダプターを一度だけ初期化します。リアクティブなプロパティであっても、アダプターの同一性が変わるとは限りません。ライフサイクルとリアクティビティを参照してください。 - プロパティは、デフォルトで親が所有するものとして扱います。コマンドにはコールバックプロパティを使用し、意図的な双方向 API(UI ラッパー、
bind:value、bind:open、bind:refなど)に限って$bindableを使用します。制御された入力では、読み取り用と書き込み用のプロパティを組み合わせるより、bind:value={get, set}を優先します。関数バインディングを参照してください。 - 新しい Svelte 5 のコードでは、スロットよりスニペットと
{@render}を優先します。公開するスニペットプロパティは、svelteのSnippetを使って型指定します。Snippet<[Row]>のように、タプル型のパラメーターを使用してください。 - ルーンズモードのコードでは、レガシーパターンを避けます。
$:宣言、export let、on:click、<slot>、<svelte:component>、<svelte:self>、beforeUpdate、afterUpdate、createEventDispatcherは使用しないでください。 - イベント属性とコールバックプロパティを使用します。
onclick={...}、onkeydown={...}、onSelect={() => ...}の形式です。新しいルーンズモードのコードにon:ディレクティブを追加したり、コンポーネントイベントをディスパッチしたりしないでください。
中核となる判断
- コンテンツの状態を追加する前に、即時編集と明示的な送信のどちらにするかを選びます。即時更新するコントロールは、現在のエディターにバインドし、完全な置き換えを送信します。明示的に送信するフォームでは、送信ごとに 1 つの下書きを管理します。できれば、置き換えによって更新する
$state.rawオブジェクトを使用してください。通常のプロキシ型$stateでは、API の境界でプレーンデータが必要な場合に$state.snapshotを使用します。リクエスト、選択状態、ウィジェットの状態は、この選択とは分けて管理してください。 - 破棄可能なリソースの識別情報が prop に依存する場合は、親側で
{#key}または{#if}を使ってマウントとアンマウントを管理し、子側ではリソースを同期的に開いてください。ライフサイクルとリアクティビティをお読みください。 - 準備完了を示す値が安定した Promise の場合は、
$state(false)フラグとキャンセル用エフェクトを使わず、テンプレートで{#await}を使ってください。 - ソースの読み取りとアクションは、使用する場所で見えるようにしてください。
session.currentやeditor.rowなどの所有者プロパティはマークアップから直接読み取り、短いガードが操作を明確にする場合も含め、転送ハンドラーは該当するコントロールのそばにインラインで記述してください。通知をエフェクトに絞り込むなど、重要な処理を説明したり必要な動作を担ったりする場合は、名前を付けてください。コンポーネントと UI のパターンおよびライフサイクルとリアクティビティをお読みください。 - 有限のユニオン型のマッピングには、ネストした三項演算子や
$derived.by()の switch ではなく、satisfies Recordのルックアップを使ってください。 get、has、size、または反復処理をリアクティブに更新する必要がある ID キー付きコレクションには、SvelteMapを使ってください。SvelteMap内の値はディーププロキシ化されないため、リアクティブな行オブジェクトを格納するか、ネストしたデータの変更時に値を置き換えてください。テーブルのようなコンシューマーに渡す前に、$derivedを使ってマップを安定した配列に変換してください。- メンバーシップ(
has、size、反復処理)がリアクティブまたはテンプレートのコンテキストで読み取られる ID セットには、SvelteSetを使ってください。add/deleteが UI を直接更新するため、$state<string[]>とスプレッド/フィルターによる再代入を置き換えられます。セットにキーごとのデータ(タイムスタンプや直近のエラーなど)が必要になった時点で、代わりにSvelteMapを使ってください。サブスクリプションのリスナーバッグなど、コレクションを命令型コードでしか読み取らない場合は、リアクティブクラスではなく通常のSet/Mapを使ってください。エフェクトの外で読み取られるリアクティブラッパーは、読み手がいないのにコストがかかります(例:createPersistedStateの通常のlistenersセット)。 - Epicenter のストアデータは、
@epicenter/svelteのfromData経由で読み取ってください。開いたデータベースの宣言済みtables/kvとpersistenceを反映し、すべての読み取りをリアクティブにし、書き込みをそのまま渡します。テーブルは行 ID をキーとするライブなSvelteMapプロジェクションとして保持され、raw ストアに対する最初のfromData呼び出し時に初期化され、各コミットで指定された ID が反映されます。同じ raw ストアに対する繰り返しの呼び出しは、テーブルを走査したり再度サブスクライブしたりせず、同じプロジェクションを返します。何も描画しない宣言済みテーブルも最初の呼び出し時には走査され、kvとpersistenceはcreateSubscriberを介して読み取り時に値を取得します。何も破棄されず、手動で破棄するものもありません。プロジェクションはドキュメントとともに破棄されます。テーブルの読み取りに、db.<table>.subscribe(listener)で$state.rawにデータを流し込む自作の仕組みは使わないでください。フィルタリングとソートには、table.rowsに対する$derivedを使ってください。テーブルではないソースから値を1つ取得する場合は、createSubscriberを手書きせず、fromSubscription(subscribe, read)を使ってください。アダプター:packages/svelte/src/from-data.svelte.ts。アプリの実例:apps/honeycrisp/src/routes/components/Notes.svelte。 - ストアではない外部イベントソース(
windowイベントや認証ストアなど)をリアクティビティに接続するには、手書きの$stateと$effect、リスナーセットではなく、svelte/reactivityのcreateSubscriberを使ってください。エフェクト内での読み取りがリアクティブになり、サブスクリプションはエフェクトの使用状況に応じて参照カウントされます(最初のサブスクライバーで開始し、ゼロでクリーンアップします)。実例:packages/auth/src/svelte/auth.svelte.ts。同じソースが、エフェクトの参照カウントでは存続期間を管理できない命令型の.get()/.watch()コンシューマーにも使われる場合に限り、手動のリスナーセットを維持してください(同じくcreatePersistedStateの例を参照してください)。 - 要素に新しい再利用可能な DOM 動作を追加する場合は、新しい
use:アクションよりも{@attach}アタッチメントを優先してください。既存のコードや、アクションしか公開していないライブラリではuse:を引き続き使ってください。 - TanStack Query のミューテーションは
.svelteファイルで作成し、独立した意味を持つヘルパーが必要な場合を除き、テンプレートハンドラーから直接mutation.mutate(...)を呼び出してください。ミューテーションとワークスペース入力をお読みください。 - レガシーな Y.Map の値フィールドについては、ミューテーションとワークスペース入力のフォーカスアウト時コミットの方針を参照してください。この方針は、入力を即時に受け付けて公開キューを所有する Folder の行エディターには適用しないでください。
- プレーンテキストと式を組み合わせる文字列属性には、JavaScript のテンプレートリテラル属性ではなく、Svelte の引用符付き補間(
label="Loading {name}"、href="/users/{id}")を使ってください。文字列以外の値、コールバック、オブジェクト、真偽値、および属性全体が計算された JavaScript 式である場合は、式属性を使ってください。 - ファイルエディターのビューには、エディターの所有パターンを使ってください。Files は全文を開き、製品リストは構造化されたコントロールを開き、無効なファイルには明示的な修復経路を用意します。詳細は取得したエディターの識別情報に紐付けてください。共有テキストコントロールは破棄されたバインディングを終了させ、受け付けた入力と保存はビューの上位にある所有者に保持させてください。
- 単純なコンポーネントの props はインラインにしてください。ラッパー、ジェネリックな関連付け、公開される契約、またはネイティブ DOM 型の合成が必要な場合に限り、名前付きの
Propsを使ってください。大きなビュー分岐は、目的を絞った子コンポーネントに移してください。コンポーネントと UI のパターンをお読みください。 - 独自のマークアップを作る前に、ローカルの
@epicenter/uiにあるローディング、空状態、保留状態、ツールチップの各コンポーネントを使ってください。
リファレンスマップ
- キー付きリソース、準備完了を示す promise、
$effectのクリーンアップ、浅いエイリアス、値のマップ、SvelteMap、テーブルの状態、または.svelte.tsの状態モジュールに関わる変更の場合は、ライフサイクルとリアクティビティを参照してください。 - TanStack Query のミューテーションの配置、インラインハンドラー、非同期ボタンの状態、直接の
await、またはワークスペースを使用するテキスト入力に関わる変更の場合は、ミューテーションとワークスペース入力を参照してください。 - shadcn-svelte のインポート、
$propsの型指定、$bindable、スニペット、DOM アタッチメント、自己完結型ダイアログ、ビューの分岐、繰り返しの多いマークアップ、単一用途ヘルパーのインライン化、読み込み中または空の状態、プロパティを優先した派生、またはテンプレートテキストの注意点に関わる変更の場合は、コンポーネントと UI のパターンを参照してください。