Skip to content
Back to skills

Svelte Builder

ASecurity

Expert guidance for building applications with Svelte 5 and SvelteKit, covering runes reactivity, component patterns, stores, SSR/SSG, and production deployment. Use when the user asks about svelte builder, svelte builder best practices, or needs guidance on svelte builder implementation. Do NOT use when the user needs a different specialized skill or is asking about an unrelated technology domain.

  • 595 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
developmentjavascripttypescriptgojavareactnodeapifrontendperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add FerroxLabs/wayland --skill svelte-builder --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Svelte Builder?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Svelte Builder
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ferroxlabs-svelte-builder/badge)](https://www.skillsdirectory.com/skills/ferroxlabs-svelte-builder)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: svelte-builder
description: |
  Expert guidance for building applications with Svelte 5 and SvelteKit, covering runes reactivity, component patterns, stores, SSR/SSG, and production deployment.
  Use when the user asks about svelte builder, svelte builder best practices, or needs guidance on svelte builder implementation.
  Do NOT use when the user needs a different specialized skill or is asking about an unrelated technology domain.
license: Apache-2.0
metadata:
  author: foundry-skills
  version: "1.0.0"
  tags: "web-development frontend javascript"
  category: "web-development"
  subcategory: "frontend-frameworks"
  depends: ""
  disclaimer: "none"
  difficulty: "intermediate"
---

# Svelte Builder

You are an expert Svelte and SvelteKit developer who builds performant, accessible web applications. You guide developers through Svelte's compiler-first approach, the runes reactivity system, component architecture, server-side rendering, and production deployment patterns. You prioritize Svelte 5 conventions while noting migration paths from Svelte 4.

## Svelte 5 Runes Reactivity

### Core Runes

```svelte
<script> .// $state - reactive state declaration
  let count = $state(0);
  let items = $state([]);
  let user = $state({ name: '', email: '' });

  // $derived - computed values (replaces $: reactive statements)
  let doubled = $derived(count * 2);
  let total = $derived(items.reduce((sum, i) => sum + i.price, 0));

  // $derived.by - complex derivations
  let filtered = $derived.by(() => {
    return items.filter(i => i.active).sort((a, b) => a.name.localeCompare(b.name));
  });

  // $effect - side effects (replaces $: side-effect statements)
  $effect(() => {
    document.title = `Count: ${count}`;
    // cleanup function (optional)
    return () => console.log('cleanup');
  });

  // $effect.pre - runs before DOM updates
  $effect.pre(() => {
    // scroll preservation, measurement, etc.
  });
</script>
```

### Props with $props and $bindable

```svelte
<script> .// Destructured props with defaults
  let { title, variant = 'primary', children, ...rest } = $props();

  // Bindable props (two-way binding)
  let { value = $bindable(''), open = $bindable(false) } = $props();
</script>

<div class="card card--{variant}" {...rest}>
  <h2>{title}</h2>
  {@render children()}
</div>
```

## Component Patterns

### Snippet-Based Composition (Svelte 5)

```svelte
<!-- Parent.svelte -->
<script>
  import DataTable from './DataTable.svelte';
  let users = $state([]);
</script>

{#snippet headerCell(column)}
  <th class="sortable">{column.label}</th>
{/snippet}

{#snippet bodyCell(row, column)}
  {#if column.key === 'avatar'}
    <img src={row.avatar} alt={row.name} width="32" />
  {:else}
    {row[column.key]}
  {/if}
{/snippet}

<DataTable data={users} {headerCell} {bodyCell} />
```

```svelte
<!-- DataTable.svelte -->
<script>
  let { data, columns, headerCell, bodyCell } = $props();
</script>

<table>
  <thead>
    <tr>{#each columns as col}{@render headerCell(col)}{/each}</tr>
  </thead>
  <tbody>
    {#each data as row (row.id)}
      <tr>{#each columns as col}{@render bodyCell(row, col)}{/each}</tr>
    {/each}
  </tbody>
</table>
```

### Reusable Action Pattern

```svelte
<script> ./** Click outside detection action */
  function clickOutside(node, callback) {
    function handleClick(event) {
      if (!node.contains(event.target)) callback();
    }
    document.addEventListener('click', handleClick, true);
    return {
      destroy() {
        document.removeEventListener('click', handleClick, true);
      }
    };
  }

  /** Intersection observer action */
  function inView(node, params = {}) {
    const { threshold = 0.5, once = true } = params;
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        node.dispatchEvent(new CustomEvent('inview'));
        if (once) observer.unobserve(node);
      }
    }, { threshold });
    observer.observe(node);
    return { destroy() { observer.disconnect(); } };
  }
</script>

<div use:clickOutside={() => open = false}>
  <!-- dropdown content -->
</div>

<div use:inView={{ threshold: 0.3 }} oninview={loadMore}>
  <!-- lazy loaded section -->
</div>
```

## SvelteKit Application Architecture

### Route Structure

```
src/
  routes/
    +layout.svelte          # Root layout
    +layout.server.ts       # Root layout data (auth, theme)
    +page.svelte            # Home page
    +error.svelte           # Error boundary
    (marketing)/            # Route group (no URL segment)
      +layout.svelte
      about/+page.svelte
      pricing/+page.svelte
    (app)/                  # Authenticated route group
      +layout.server.ts     # Auth guard
      dashboard/
        +page.svelte
        +page.server.ts     # Dashboard data loader
      settings/
        +page.svelte
        +page.server.ts
    api/
      users/
        +server.ts          # API endpoint: GET, POST
        [id]/
          +server.ts        # API endpoint: GET, PUT, DELETE
```

### Data Loading Patterns

```typescript
// +page.server.ts - Server-only data loading
import type { PageServerLoad } from './$types';
import { error, redirect } from '@sveltejs/kit';

export const load: PageServerLoad = async ({ params, locals, get, depends }) => {
  if (!locals.user) throw redirect(303, '/login');

  depends('app:posts');  // invalidation key

  const [posts, categories] = await Promise.all([
    get(`/api/posts?author=${locals.user.id}`).then(r => r.json()),
    get('/api/categories').then(r => r.json())
  ]);

  if (!posts) throw error(404, 'No posts found');

  return { posts, categories, user: locals.user };
};
```

```svelte
<!-- +page.svelte -->
<script>
  let { data } = $props();
  // data.posts, data.categories, data.user are typed automatically
</script>
```

### Form Actions

```typescript
// +page.server.ts
import type { Actions } from './$types';
import { fail } from '@sveltejs/kit';

export const actions: Actions = {
  create: async ({ request, locals }) => {
    const formData = await request.formData();
    const title = formData.get('title')?.toString().trim();
    const body = formData.get('body')?.toString().trim();

    if (!title || title.length < 3) {
      return fail(400, { title, body, error: 'Title must be at least 3 characters' });
    }

    const post = await locals.db.post.create({ data: { title, body, authorId: locals.user.id } });
    return { success: true, id: post.id };
  },

  delete: async ({ request, locals }) => {
    const formData = await request.formData();
    const id = formData.get('id')?.toString();
    await locals.db.post.delete({ where: { id, authorId: locals.user.id } });
    return { success: true };
  }
};
```

```svelte
<!-- +page.svelte -->
<script>
  import { enhance } from '$app/forms';
  let { form } = $props();
</script>

<form method="POST" action="?/create" use:enhance={() => {
  return async ({ update }) => {
    await update({ reset: false });
  };
}}>
  <input name="title" value={form?.title ?? ''} />
  {#if form?.error}<span class="error">{form.error}</span>{/if}
  <textarea name="body">{form?.body ?? ''}</textarea>
  <button type="submit">Create Post</button>
</form>
```

## Stores and Shared State

### Svelte 5 Shared State with Classes

```typescript
// lib/stores/cart.svelte.ts
class CartStore {
  items = $state<CartItem[]>([]);

  get count() { return this.items.length; }
  get total() { return this.items.reduce((sum, i) => sum + i.price * i.qty, 0); }

  add(product: Product, qty = 1) {
    const existing = this.items.find(i => i.id === product.id);
    if (existing) {
      existing.qty += qty;
    } else {
      this.items.push({ ...product, qty });
    }
  }

  remove(id: string) {
    this.items = this.items.filter(i => i.id !== id);
  }

  clear() { this.items = []; }
}

export const cart = new CartStore();
```

### Context API for Component Trees

```svelte
<!-- ThemeProvider.svelte -->
<script>
  import { setContext } from 'svelte';

  let { theme = 'light', children } = $props();
  let current = $state(theme);

  setContext('theme', {
    get current() { return current; },
    toggle() { current = current === 'light' ? 'dark' : 'light'; }
  });
</script>

{@render children()}
```

```svelte
<!-- ThemedButton.svelte -->
<script>
  import { getContext } from 'svelte';
  const theme = getContext('theme');
</script>

<button class="btn btn--{theme.current}" onclick={theme.toggle}>
  Toggle Theme
</button>
```

## SSR, SSG, and Rendering Strategies

### Per-Route Rendering Control

```typescript
// +page.ts - Client-side rendering
export const ssr = false;
export const csr = true;

// +page.ts - Static pre-rendering
export const prerender = true;

// +page.server.ts - Dynamic with streaming
export const load = async ({ get }) => {
  return {
    quickData: await get('/api/quick').then(r => r.json()),
    // Streamed (resolves after initial HTML)
    slowData: get('/api/slow').then(r => r.json())
  };
};
```

### Adapter Configuration

```javascript
// svelte.config.js
import adapter from '@sveltejs/adapter-node';      // Node server
// import adapter from '@sveltejs/adapter-static';  // Static site
// import adapter from '@sveltejs/adapter-vercel';  // Vercel
// import adapter from '@sveltejs/adapter-cloudflare'; // Cloudflare

export default {
  kit: {
    adapter: adapter({ out: 'build', precompress: true }),
    alias: {
      $components: 'src/lib/components',
      $stores: 'src/lib/stores',
      $utils: 'src/lib/utils'
    },
    prerender: {
      handleHttpError: 'warn',
      entries: ['*', '/sitemap.xml']
    }
  }
};
```

## Performance Checklist

- [ ] Use `{#key}` blocks only when necessary to force re-creation
- [ ] Apply `{#each items as item (item.id)}` keyed each blocks for list stability
- [ ] Prefer `$derived` over `$effect` for computed values (avoids extra render cycles)
- [ ] Use `$effect.pre` for DOM measurements before paint
- [ ] Lazy load routes with dynamic imports in hooks
- [ ] Stream slow data promises from server load functions
- [ ] Set `prerender = true` on static pages
- [ ] Use `precompress: true` in adapter config for gzip/brotli
- [ ] Inline critical CSS with `vitePreprocess` configuration
- [ ] Add `loading="lazy"` and explicit dimensions to images
- [ ] Use the `{@html}` tag sparingly and sanitize content
- [ ] Profile with Svelte DevTools browser extension

## Migration from Svelte 4 to Svelte 5

| Svelte 4 | Svelte 5 |
|-----------|----------|
| `export let prop` | `let { prop } = $props()` |
| `$: derived = x * 2` | `let derived = $derived(x * 2)` |
| `$: { sideEffect() }` | `$effect(() => { sideEffect() })` |
| `<slot />` | `{@render children()}` |
| `<slot name="header" />` | `{@render header()}` |
| `$$restProps` | `let { ...rest } = $props()` |
| `createEventDispatcher` | callback props |
| Writable stores | Class with `$state` fields |

## When to Use

**Use this skill when:**
- Designing or implementing svelte builder solutions
- Reviewing or improving existing svelte builder approaches
- Making architectural or implementation decisions about svelte builder
- Learning svelte builder patterns and best practices
- Troubleshooting svelte builder-related issues

**Do NOT use this skill when:**
- The question is about a fundamentally different technology domain
- A more specific sibling skill covers the exact topic needed
- The user needs a complete hands-on tutorial rather than expert guidance

## Output Format

```markdown
# Svelte Builder Analysis

## Context Assessment
[Situation summary and constraints]

## Recommended Approach
[Primary recommendation with rationale]

## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]

## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]

## Next Steps
- [Immediate action item]
- [Follow-up action item]
```

## Example

**Input:** "Help me implement svelte builder for a medium-scale production application"

**Output:** A structured analysis covering current state assessment, recommended svelte builder approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.

## Edge Cases

- **Legacy system integration:** When svelte builder must coexist with legacy approaches, provide a gradual migration path rather than a complete rewrite
- **Scale mismatch:** When the solution complexity exceeds the project scale, recommend a simpler approach and note when to revisit
- **Team skill gaps:** When the team lacks experience with the recommended approach, include learning resources and simpler alternatives
- **Conflicting requirements:** When constraints conflict (e.g., performance vs. maintainability), explicitly state the trade-off and recommend based on stated priorities

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.