Only use the $state rune for variables that should be reactive — in other words, variables that cause an $effect, $derived or template expression to update. Everything else can be a normal variable.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionsvelte-core-bestpracticesExecute the skills CLI command in your project's root directory to begin installation:
Fetches svelte-core-bestpractices from sveltejs/ai-tools and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate svelte-core-bestpractices. Access via /svelte-core-bestpractices in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
2
total installs
2
this week
225
GitHub stars
0
upvotes
Run in your terminal
2
installs
2
this week
225
stars
$stateOnly use the $state rune for variables that should be reactive — in other words, variables that cause an $effect, $derived or template expression to update. Everything else can be a normal variable.
Objects and arrays ($state({...}) or $state([...])) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you're dealing with large objects that are only ever reassigned (rather than mutated), use $state.raw instead. This is often the case with API responses, for example.
$derivedTo compute something from state, use $derived rather than $effect:
// do this
let square = $derived(num * num);
// don't do this
let square;
$effect(() => {
square = num * num;
});
[!NOTE]
$derivedis given an expression, not a function. If you need to use a function (because the expression is complex, for example) use$derived.by.
Deriveds are writable — you can assign to them, just like $state, except that they will re-evaluate when their expression changes.
If the derived expression is an object or array, it will be returned as-is — it is not made deeply reactive. You can, however, use $state inside $derived.by in the rare cases that you need this.
$effectEffects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.
{@attach ...}$inspectcreateSubscriberNever wrap the contents of an effect in if (browser) {...} or similar — effects do not run on the server.
$propsTreat props as though they will change. For example, values that depend on props should usually use $derived:
// @errors: 2451
let { type } = $props();
// do this
let color = $derived(type === 'danger' ? 'red' : 'green');
// don't do this — `color` will not update if `type` changes
let color = type === 'danger' ? 'red' : 'green';
$inspect.trace$inspect.trace is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add $inspect.trace(label) as the first line of an $effect or $derived.by (or any function they call) to trace their dependencies and discover which one triggered an update.
Any element attribute starting with on is treated as an event listener:
<button onclick={() => {...}}>click me</button>
<!-- attribute shorthand also works -->
<button {onclick}>...</button>
<!-- so do spread attributes -->
<button {...props}>...</button>
If you need to attach listeners to window or document you can use <svelte:window> and <svelte:document>:
<svelte:window onkeydown={...} />
<svelte:document onvisibilitychange={...} />
Avoid using onMount or $effect for this.
Snippets are a way to define reusable chunks of markup that can be instantiated with the {@render ...} tag, or passed to components as props. They must be declared within the template.
{#snippet greeting(name)}
<p>hello {name}!</p>
{/snippet}
{@render greeting('world')}
[!NOTE] Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside
<script>. A snippet that doesn't reference component state is also available in a<script module>, in which case it can be exported for use by other components.
Prefer to use keyed each blocks — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.
[!NOTE] The key must uniquely identify the object. Do not use the index as a key.
Avoid destructuring if you need to mutate the item (with something like bind:value={item.count}, for example).
If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the style: directive.
<div style:--columns={columns}>...</div>
You can then reference var(--columns) inside the component's <style>.
The CSS in a component's <style> is scoped to that component. If a parent component needs to control the child's styles, the preferred way is to use CSS custom properties:
<!-- Parent.svelte -->
<Child --color="red" />
<!-- Child.svelte -->
<h1>Hello</h1>
<style>
h1 {
color: var(--color);
}
</style>
If this is impossible (for example, the child component comes from a library) you can use :global to override styles:
<div>
<Child />
</div>
<style>
div :global {
h1 {
color: red;
}
}
</style>
Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.
Use createContext rather than setContext and getContext, as it provides type safety.
If using version 5.36 or higher, you can use await expressions and hydratable to use promises directly inside components. Note that these require the experimental.async option to be enabled in svelte.config.js as they are not yet considered fully stable.
Always use runes mode for new code, and avoid features that have more modern replacements:
$state instead of implicit reactivity (e.g. let count = 0; count += 1)$derived and $effect instead of $: assignments and statements (but only use effects when there is no better solution)$props instead of export let, $$props and $$restPropsonclick={...} instead of on:click={...}{#snippet ...} and {@render ...} instead of <slot> and $$slots and <svelte:fragment><DynamicComponent> instead of <svelte:component this={DynamicComponent}>import Self from './ThisComponent.svelte' and <Self> instead of <svelte:self>$state fields to share reactivity between components, instead of using stores{@attach ...} instead of use:actionclass attributes, instead of the class: directivePrerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
anthropics/claude-code
mblode/agent-skills
github/awesome-copilot
leonxlnx/taste-skill
sickn33/antigravity-awesome-skills
erichowens/some_claude_skills
I recommend svelte-core-bestpractices for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
svelte-core-bestpractices reduced setup friction for our internal harness; good balance of opinion and flexibility.
svelte-core-bestpractices fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
We added svelte-core-bestpractices from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
Useful defaults in svelte-core-bestpractices — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
svelte-core-bestpractices has been reliable in day-to-day use. Documentation quality is above average for community skills.
Solid pick for teams standardizing on skills: svelte-core-bestpractices is focused, and the summary matches what you get after install.
svelte-core-bestpractices has been reliable in day-to-day use. Documentation quality is above average for community skills.
Useful defaults in svelte-core-bestpractices — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
svelte-core-bestpractices has been reliable in day-to-day use. Documentation quality is above average for community skills.
showing 1-10 of 39