Skip to main content Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill svelte5-runes-staticLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt LinkedIn automation via the Linked API CLI - fetch profiles, search people and companies, send messages, manage connections, create posts, react, comment, and run Sales Navigator and custom workflows. Use when the user wants to interact with LinkedIn.
Xquik X data automation API - Use REST or MCP for tweet search, user lookup, follower exports, media downloads, monitors, webhooks, giveaway draws, and confirmation-gated X actions.
MCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
Métiers associés SOC
Basé sur la classification professionnelle SOC
Explorateur de fichiers
2 fichiers name svelte5-runes-static description Svelte 5 runes + SvelteKit adapter-static (SSG/SSR) patterns for hydration-safe state, store bridges, and reactivity that survives prerendering user-invocable false disable-model-invocation true version 1.0.0 category toolchain author Claude MPM Team license MIT progressive_disclosure {"entry_point":{"summary":"Hydration-safe Svelte 5 runes patterns for SvelteKit adapter-static (SSG/SSR)","when_to_use":"When using Svelte 5 runes with SvelteKit prerendering/adapter-static and encountering frozen state, hydration mismatches, or store bridge issues","quick_start":"1. Keep global state in writable()/derived() 2. Bridge store → $state in $effect() 3. Use $derived() for computations 4. Guard client-only code with browser"}} context_limit 150 tags ["svelte","svelte5","sveltekit","runes","adapter-static","ssr","ssg","hydration","stores","reactivity","prerendering","typescript"] requires_tools []
Svelte 5 Runes with adapter-static (SvelteKit)
Overview
Build static-first SvelteKit applications with Svelte 5 runes without breaking hydration. Apply these patterns when using adapter-static (prerendering) and combining global stores with component-local runes.
Related Skills
svelte (Svelte 5 runes core patterns)
sveltekit (adapters, deployment, SSR/SSG patterns)
typescript-core (TypeScript patterns and validation)
vitest (unit testing patterns)
Core Expertise
Building static-first Svelte 5 applications using runes mode with proper state management patterns that survive prerendering and hydration.
Critical Compatibility Rules
❌ NEVER: Runes in Module Scope with adapter-static
Problem : Runes don't hydrate properly after static prerendering
export function createStore ( ) {
let state = $state({ count : 0 });
return {
get count () { return state.count ; },
increment : () => { state.count ++; }
};
}
Why it fails :
adapter-static prerenders components to HTML
Runes in module scope don't serialize/deserialize
State becomes inert/frozen after hydration
Reactivity completely breaks
Solution : Use traditional writable() stores for global state
import { writable } from 'svelte/store' ;
export function ( ) {
count = ( );
{
count,
: count. ( n + )
};
}
createStore
const
writable
0
return
increment
() =>
update
n =>
1
❌ NEVER: $ Auto-subscription Inside $derived Problem : Runes mode disables $ auto-subscription syntax
let filtered = $derived($events.filter (e => e.type === 'info' ));
Solution : Subscribe in $effect() → update $state() → use in $derived()
import { type Writable } from 'svelte/store' ;
let events = $state<Event []>([]);
$effect(() => {
const unsub = eventsStore.subscribe (value => {
events = value;
});
return unsub;
});
let filtered = $derived(events.filter (e => e.type === 'info' ));
❌ NEVER: Store Factory with Getters Problem : Getters don't establish reactive connections
export function createSocketStore ( ) {
const socket = writable<Socket | null >(null );
return {
get socket () { return socket; },
connect : () => { }
};
}
Solution : Export stores directly
export function createSocketStore ( ) {
const socket = writable<Socket | null >(null );
const isConnected = derived (socket, $s => $s?.connected ?? false );
return {
socket,
isConnected,
connect : () => { }
};
}
Recommended Hybrid Pattern
Global State: Traditional Stores Use writable()/derived() for state that needs to survive SSG/SSR:
import { writable, derived } from 'svelte/store' ;
export const user = writable<User | null >(null );
export const theme = writable<'light' | 'dark' >('light' );
export const isAuthenticated = derived (user, $u => $u !== null );
Component State: Svelte 5 Runes Use runes for component-local state and logic:
<script lang="ts" >
import { user } from '$lib/stores/globalState' ;
let {
initialCount = 0 ,
onUpdate = () => {}
}: {
initialCount ?: number ;
onUpdate ?: (count : number ) => void ;
} = $props();
let currentUser = $state<User | null >(null );
$effect(() => {
const unsub = user.subscribe (u => {
currentUser = u;
});
return unsub;
});
let count = $state(initialCount);
let doubled = $derived(count * 2 );
$effect(() => {
if (count > 10 ) {
onUpdate (count);
}
});
function increment ( ) {
count++;
}
</script>
<button onclick ={increment} >
{currentUser?.name ?? 'Guest'}: {count} (×2 = {doubled})
</button >
Complete Bridge Pattern
Store → Rune → Derived Chain <script lang="ts" >
import { type Writable } from 'svelte/store' ;
const { events : eventsStore, filters : filtersStore } = myGlobalStore;
let events = $state<Event []>([]);
let activeFilters = $state<string []>([]);
$effect(() => {
const unsubEvents = eventsStore.subscribe (v => { events = v; });
const unsubFilters = filtersStore.subscribe (v => { activeFilters = v; });
return () => {
unsubEvents ();
unsubFilters ();
};
});
let filtered = $derived(
events.filter (e =>
activeFilters.length === 0 ||
activeFilters.includes (e.category )
)
);
let count = $derived(filtered.length );
let hasEvents = $derived(count > 0 );
</script>
{#if hasEvents}
<p>Found {count} events</p>
{#each filtered as event}
<EventCard {event} />
{/each}
{:else }
<p>No events match filters</p>
{/if }
SSG/SSR Considerations
Prerender-Safe Patterns
export const load = async ({ fetch } ) => {
const data = await fetch ('/api/data' ).then (r => r.json ());
return { data };
};
<script lang="ts">
import { browser } from '$app/environment';
let { data } = $props();
// ✅ Client-only initialization
$effect(() => {
if (browser) {
// WebSocket, localStorage, etc.
initializeClientOnlyFeatures();
}
});
</script>
Hydration Mismatch Prevention
let timestamp = $state<number | null >(null );
$effect(() => {
if (browser) {
timestamp = Date .now ();
}
});
<!-- ✅ Conditional rendering for client-only content -->
{#if browser}
<LiveClock />
{:else}
<p>Loading clock...</p>
{/if}
TypeScript Integration
Typed Props with Runes <script lang="ts" >
import type { Snippet } from 'svelte' ;
interface Props {
title : string ;
count ?: number ;
items : Array <{ id : string ; name : string }>;
onSelect ?: (id : string ) => void ;
children ?: Snippet ;
}
let {
title,
count = 0 ,
items,
onSelect = () => {},
children
}: Props = $props();
let selected = $state<string | null >(null );
let filteredItems = $derived(
items.filter (item =>
selected === null || item.id === selected
)
);
</script>
<h2 > {title} ({count})</h2 >
{#each filteredItems as item}
<button onclick={() => onSelect (item.id )}>
{item.name }
</button>
{/each}
{@render children?.()}
Typed Store Bridges <script lang="ts" >
import type { Writable , Readable } from 'svelte/store' ;
interface StoreShape {
data : Writable <string []>;
status : Readable <'loading' | 'ready' | 'error' >;
}
const stores : StoreShape = getMyStores ();
let data = $state<string []>([]);
let status = $state<'loading' | 'ready' | 'error' >('loading' );
$effect(() => {
const unsubData = stores.data .subscribe (v => { data = v; });
const unsubStatus = stores.status .subscribe (v => { status = v; });
return () => {
unsubData ();
unsubStatus ();
};
});
let isEmpty = $derived(data.length === 0 );
let isReady = $derived(status === 'ready' );
</script>
Common Patterns
Bindable Component State <script lang="ts" >
let {
value = $bindable('' ),
disabled = false
}: {
value ?: string ;
disabled ?: boolean ;
} = $props();
let focused = $state(false );
let charCount = $derived(value.length );
let isValid = $derived(charCount >= 3 && charCount <= 100 );
</script>
<input
bind:value
{disabled }
onfocus ={() => { focused = true; }}
onblur={() => { focused = false; }}
class:focused
class:invalid={!isValid}
/>
<p > {charCount}/100</p >
Form State Management <script lang="ts" >
interface FormData {
email : string ;
password : string ;
}
let formData = $state<FormData >({
email : '' ,
password : ''
});
let errors = $state<Partial <Record <keyof FormData , string >>>({});
let isValid = $derived(
formData.email .includes ('@' ) &&
formData.password .length >= 8
);
let canSubmit = $derived(
isValid && Object .keys (errors).length === 0
);
function validate (field : keyof FormData ) {
if (field === 'email' && !formData.email .includes ('@' )) {
errors.email = 'Invalid email' ;
} else if (field === 'password' && formData.password .length < 8 ) {
errors.password = 'Password too short' ;
} else {
delete errors[field];
}
}
async function handleSubmit ( ) {
if (!canSubmit) return ;
const result = await submitForm (formData);
if (result.ok ) {
} else {
errors = result.errors ;
}
}
</script>
<form onsubmit ={handleSubmit} >
<input
type ="email"
bind:value ={formData.email}
onblur ={() => validate('email')}
/>
{#if errors.email}
<span class ="error" > {errors.email}</span >
{/if}
<input
type ="password"
bind:value ={formData.password}
onblur ={() => validate('password')}
/>
{#if errors.password}
<span class ="error" > {errors.password}</span >
{/if}
<button type ="submit" disabled ={!canSubmit} >
Submit
</button >
</form >
Debounced Search <script lang="ts" >
import { writable, derived } from 'svelte/store' ;
const searchQuery = writable ('' );
const debouncedQuery = derived (
searchQuery,
($query, set ) => {
const timeout = setTimeout (() => set ($query), 300 );
return () => clearTimeout (timeout);
},
''
);
let query = $state('' );
let debouncedValue = $state('' );
$effect(() => {
searchQuery.set (query);
});
$effect(() => {
const unsub = debouncedQuery.subscribe (v => {
debouncedValue = v;
});
return unsub;
});
let results = $derived(
debouncedValue.length >= 3
? performSearch (debouncedValue)
: []
);
</script>
<input
type ="search"
bind:value ={query}
placeholder ="Search..."
/>
{#each results as result}
<SearchResult {result} />
{/each}
Migration Checklist When migrating from Svelte 4 to Svelte 5 with adapter-static:
Testing Patterns
Unit Testing Runes import { mount } from 'svelte' ;
import { tick } from 'svelte' ;
import { describe, it, expect } from 'vitest' ;
import Counter from './Counter.svelte' ;
describe ('Counter' , () => {
it ('increments count' , async () => {
const { component } = mount (Counter , {
target : document .body ,
props : { initialCount : 0 }
});
const button = document .querySelector ('button' );
button?.click ();
await tick ();
expect (button?.textContent ).toContain ('1' );
});
});
Testing Store Bridges import { get } from 'svelte/store' ;
import { tick } from 'svelte' ;
import { describe, it, expect } from 'vitest' ;
import { createMyStore } from './myStore' ;
describe ('Store Bridge' , () => {
it ('syncs store to rune state' , async () => {
const store = createMyStore ();
store.data .set (['item1' , 'item2' ]);
await tick ();
expect (get (store.data )).toEqual (['item1' , 'item2' ]);
});
});
Performance Considerations
Avoid Unnecessary Reactivity
let items = $state([1 , 2 , 3 , 4 , 5 ]);
let doubled = $derived(items.map (x => x * 2 ));
let tripled = $derived(items.map (x => x * 3 ));
let quadrupled = $derived(items.map (x => x * 4 ));
let items = $state([1 , 2 , 3 , 4 , 5 ]);
let transformedItems = $derived(
mode === 'double' ? items.map (x => x * 2 ) :
mode === 'triple' ? items.map (x => x * 3 ) :
items.map (x => x * 4 )
);
Memoize Expensive Computations
const expensiveComputation = derived (
[source1, source2],
([$s1, $s2] ) => {
return complexAlgorithm ($s1, $s2);
}
);
let result = $state(null );
$effect(() => {
const unsub = expensiveComputation.subscribe (v => { result = v; });
return unsub;
});
Troubleshooting
Symptom: State doesn't update after hydration Cause : Runes in module scope with adapter-static
Fix : Use traditional writable() stores for global state
Symptom: "$ is not defined" error in $derived Cause : Trying to use $store syntax in runes mode
Fix : Use bridge pattern with $effect() subscription
Symptom: "Cannot read property of undefined" after SSG Cause : Store factory with getters instead of direct exports
Fix : Export stores directly, not wrapped in getters
Symptom: Hydration mismatch warnings Cause : Client-only state rendered during SSR
Fix : Guard with browser check or use {#if browser}
Decision Framework Use Traditional Stores When:
State needs to survive SSG/SSR prerendering
State is global/shared across components
State needs to be serialized/deserialized
Working with adapter-static
State is component-local
Building reactive UI logic
Working with props and component lifecycle
Creating derived computations from local state
Need to combine global stores with component runes
Want derived computations from store values
Building complex reactive chains
Related Skills
toolchains-javascript-frameworks-svelte : Base Svelte patterns
toolchains-typescript-core : TypeScript integration
toolchains-ui-styling-tailwind : Styling Svelte components
toolchains-javascript-testing-vitest : Testing Svelte 5
References