sveltekit

Expert guidance for building modern, performant web applications with SvelteKit.

16 stars

Best use case

sveltekit is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Expert guidance for building modern, performant web applications with SvelteKit.

Teams using sveltekit should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/sveltekit/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/sveltekit/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/sveltekit/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How sveltekit Compares

Feature / AgentsveltekitStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Expert guidance for building modern, performant web applications with SvelteKit.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# SvelteKit Frontend Development Skill

## Overview
Expert guidance for building modern, performant web applications with SvelteKit.

## When to Use This Skill
- Creating new SvelteKit applications
- Building user interfaces and components
- Implementing client-server communication with Eden Treaty
- Setting up routing and layouts
- Managing state and forms

## Stack Context
- **Framework:** SvelteKit
- **Runtime:** Bun (dev server)
- **API Client:** Eden Treaty (type-safe ElysiaJS client)
- **Code Style:** Standard JS (no semicolons)
- **Build:** Vite (bundled with SvelteKit)

## Project Structure

```
packages/web/
├── src/
│   ├── routes/
│   │   ├── +page.svelte           # Home page
│   │   ├── +layout.svelte         # Root layout
│   │   ├── users/
│   │   │   ├── +page.svelte       # Users list
│   │   │   └── [id]/
│   │   │       └── +page.svelte   # User detail
│   │   └── api/
│   │       └── client.js          # API client
│   ├── lib/
│   │   ├── components/
│   │   │   ├── Header.svelte
│   │   │   └── Button.svelte
│   │   ├── stores/
│   │   │   └── user.js
│   │   └── utils/
│   │       └── format.js
│   └── app.html                   # HTML template
├── static/
│   └── favicon.png
├── package.json
├── svelte.config.js
└── vite.config.js
```

## Workflows

### 1. Initialize SvelteKit Project

```bash
# Create package
mkdir -p packages/web
cd packages/web

# Initialize SvelteKit
bun create svelte@latest .

# Select options:
# - Skeleton project
# - TypeScript: No (using JS)
# - Add ESLint: Yes
# - Add Prettier: Yes

# Install dependencies
bun install

# Add Eden Treaty for API client
bun add @elysiajs/eden
```

`package.json`:
```json
{
  "name": "@monorepo/web",
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "dev": "vite dev",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "standard"
  },
  "dependencies": {
    "@elysiajs/eden": "^1.0.0"
  },
  "devDependencies": {
    "@sveltejs/adapter-auto": "^3.0.0",
    "@sveltejs/kit": "^2.0.0",
    "@sveltejs/vite-plugin-svelte": "^3.0.0",
    "svelte": "^4.0.0",
    "vite": "^5.0.0"
  }
}
```

### 2. Basic SvelteKit Configuration

`svelte.config.js`:
```javascript
import adapter from '@sveltejs/adapter-auto'

export default {
  kit: {
    adapter: adapter()
  }
}
```

`vite.config.js`:
```javascript
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [sveltekit()],
  server: {
    port: 5173
  }
})
```

### 3. API Client Setup with Eden Treaty

`src/lib/api/client.js`:
```javascript
import { edenTreaty } from '@elysiajs/eden'

const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000'

export const api = edenTreaty(API_URL)

// Helper functions
export async function getUsers () {
  const { data, error } = await api.users.get()
  if (error) throw new Error(error.message || 'Failed to fetch users')
  return data.users
}

export async function getUser (id) {
  const { data, error } = await api.users[id].get()
  if (error) throw new Error(error.message || 'Failed to fetch user')
  return data.user
}

export async function createUser (userData) {
  const { data, error } = await api.users.post(userData)
  if (error) throw new Error(error.message || 'Failed to create user')
  return data
}

export async function updateUser (id, userData) {
  const { data, error } = await api.users[id].put(userData)
  if (error) throw new Error(error.message || 'Failed to update user')
  return data
}

export async function deleteUser (id) {
  const { data, error } = await api.users[id].delete()
  if (error) throw new Error(error.message || 'Failed to delete user')
  return data
}
```

`.env`:
```bash
VITE_API_URL=http://localhost:3000
```

### 4. Root Layout

`src/routes/+layout.svelte`:
```svelte
<script>
  import '../app.css'
</script>

<div class="app">
  <header>
    <nav>
      <a href="/">Home</a>
      <a href="/users">Users</a>
      <a href="/posts">Posts</a>
    </nav>
  </header>

  <main>
    <slot />
  </main>

  <footer>
    <p>&copy; 2024 My App</p>
  </footer>
</div>

<style>
  .app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }

  header {
    background: #333;
    color: white;
    padding: 1rem;
  }

  nav {
    display: flex;
    gap: 1rem;
  }

  nav a {
    color: white;
    text-decoration: none;
  }

  nav a:hover {
    text-decoration: underline;
  }

  main {
    flex: 1;
    padding: 2rem;
    max-width: 1200px;
    margin: 0 auto;
    width: 100%;
  }

  footer {
    background: #f5f5f5;
    padding: 1rem;
    text-align: center;
  }
</style>
```

### 5. Home Page

`src/routes/+page.svelte`:
```svelte
<script>
  let name = 'World'
</script>

<svelte:head>
  <title>Home</title>
</svelte:head>

<div class="container">
  <h1>Welcome to SvelteKit</h1>
  <p>Hello {name}!</p>
  
  <input bind:value={name} placeholder="Enter your name" />
</div>

<style>
  .container {
    text-align: center;
  }

  h1 {
    font-size: 3rem;
    margin-bottom: 1rem;
  }

  input {
    padding: 0.5rem;
    font-size: 1rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    margin-top: 1rem;
  }
</style>
```

### 6. Page with Server Load

`src/routes/users/+page.js`:
```javascript
import { getUsers } from '$lib/api/client'

export async function load () {
  try {
    const users = await getUsers()
    return { users }
  } catch (error) {
    return {
      users: [],
      error: error.message
    }
  }
}
```

`src/routes/users/+page.svelte`:
```svelte
<script>
  export let data
</script>

<svelte:head>
  <title>Users</title>
</svelte:head>

<div class="container">
  <h1>Users</h1>

  {#if data.error}
    <p class="error">{data.error}</p>
  {:else if data.users.length === 0}
    <p>No users found.</p>
  {:else}
    <ul class="users-list">
      {#each data.users as user}
        <li>
          <a href="/users/{user._id}">
            <h3>{user.name}</h3>
            <p>{user.email}</p>
          </a>
        </li>
      {/each}
    </ul>
  {/if}

  <a href="/users/new" class="button">Create User</a>
</div>

<style>
  .container {
    max-width: 800px;
  }

  .users-list {
    list-style: none;
    padding: 0;
    display: grid;
    gap: 1rem;
  }

  .users-list li {
    background: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 1rem;
    transition: box-shadow 0.2s;
  }

  .users-list li:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  .users-list a {
    text-decoration: none;
    color: inherit;
  }

  .users-list h3 {
    margin: 0 0 0.5rem 0;
  }

  .users-list p {
    margin: 0;
    color: #666;
  }

  .button {
    display: inline-block;
    margin-top: 2rem;
    padding: 0.75rem 1.5rem;
    background: #0066cc;
    color: white;
    text-decoration: none;
    border-radius: 4px;
  }

  .button:hover {
    background: #0052a3;
  }

  .error {
    color: red;
    padding: 1rem;
    background: #ffe6e6;
    border-radius: 4px;
  }
</style>
```

### 7. Dynamic Route

`src/routes/users/[id]/+page.js`:
```javascript
import { getUser } from '$lib/api/client'
import { error } from '@sveltejs/kit'

export async function load ({ params }) {
  try {
    const user = await getUser(params.id)
    return { user }
  } catch (err) {
    throw error(404, 'User not found')
  }
}
```

`src/routes/users/[id]/+page.svelte`:
```svelte
<script>
  export let data
</script>

<svelte:head>
  <title>{data.user.name}</title>
</svelte:head>

<div class="container">
  <h1>{data.user.name}</h1>
  <p><strong>Email:</strong> {data.user.email}</p>
  <p><strong>Created:</strong> {new Date(data.user.createdAt).toLocaleDateString()}</p>
  
  <div class="actions">
    <a href="/users/{data.user._id}/edit" class="button">Edit</a>
    <a href="/users" class="button secondary">Back to Users</a>
  </div>
</div>

<style>
  .container {
    max-width: 600px;
  }

  .actions {
    display: flex;
    gap: 1rem;
    margin-top: 2rem;
  }

  .button {
    padding: 0.75rem 1.5rem;
    background: #0066cc;
    color: white;
    text-decoration: none;
    border-radius: 4px;
  }

  .button:hover {
    background: #0052a3;
  }

  .button.secondary {
    background: #666;
  }

  .button.secondary:hover {
    background: #555;
  }
</style>
```

### 8. Form with Actions

`src/routes/users/new/+page.server.js`:
```javascript
import { createUser } from '$lib/api/client'
import { redirect } from '@sveltejs/kit'

export const actions = {
  default: async ({ request }) => {
    const formData = await request.formData()
    const name = formData.get('name')
    const email = formData.get('email')

    try {
      await createUser({ name, email })
      throw redirect(303, '/users')
    } catch (error) {
      return {
        error: error.message,
        name,
        email
      }
    }
  }
}
```

`src/routes/users/new/+page.svelte`:
```svelte
<script>
  import { enhance } from '$app/forms'
  export let form
</script>

<svelte:head>
  <title>Create User</title>
</svelte:head>

<div class="container">
  <h1>Create User</h1>

  {#if form?.error}
    <p class="error">{form.error}</p>
  {/if}

  <form method="POST" use:enhance>
    <div class="field">
      <label for="name">Name</label>
      <input
        id="name"
        name="name"
        type="text"
        required
        value={form?.name || ''}
      />
    </div>

    <div class="field">
      <label for="email">Email</label>
      <input
        id="email"
        name="email"
        type="email"
        required
        value={form?.email || ''}
      />
    </div>

    <div class="actions">
      <button type="submit">Create User</button>
      <a href="/users" class="button secondary">Cancel</a>
    </div>
  </form>
</div>

<style>
  .container {
    max-width: 600px;
  }

  .field {
    margin-bottom: 1rem;
  }

  label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
  }

  input {
    width: 100%;
    padding: 0.75rem;
    font-size: 1rem;
    border: 1px solid #ccc;
    border-radius: 4px;
  }

  .actions {
    display: flex;
    gap: 1rem;
    margin-top: 2rem;
  }

  button {
    padding: 0.75rem 1.5rem;
    background: #0066cc;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
  }

  button:hover {
    background: #0052a3;
  }

  .button.secondary {
    background: #666;
    text-decoration: none;
    padding: 0.75rem 1.5rem;
    color: white;
    border-radius: 4px;
  }

  .error {
    color: red;
    padding: 1rem;
    background: #ffe6e6;
    border-radius: 4px;
    margin-bottom: 1rem;
  }
</style>
```

### 9. Reusable Components

`src/lib/components/Button.svelte`:
```svelte
<script>
  export let variant = 'primary'
  export let type = 'button'
  export let href = null
</script>

{#if href}
  <a {href} class="button {variant}">
    <slot />
  </a>
{:else}
  <button {type} class="button {variant}" on:click>
    <slot />
  </button>
{/if}

<style>
  .button {
    padding: 0.75rem 1.5rem;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    text-decoration: none;
    display: inline-block;
  }

  .button.primary {
    background: #0066cc;
    color: white;
  }

  .button.primary:hover {
    background: #0052a3;
  }

  .button.secondary {
    background: #666;
    color: white;
  }

  .button.secondary:hover {
    background: #555;
  }

  .button.danger {
    background: #cc0000;
    color: white;
  }

  .button.danger:hover {
    background: #a30000;
  }
</style>
```

Usage:
```svelte
<script>
  import Button from '$lib/components/Button.svelte'
</script>

<Button>Default Button</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="danger">Delete</Button>
<Button href="/users">Link Button</Button>
```

### 10. Stores for State Management

`src/lib/stores/user.js`:
```javascript
import { writable } from 'svelte/store'

export const currentUser = writable(null)

export function setUser (user) {
  currentUser.set(user)
}

export function clearUser () {
  currentUser.set(null)
}
```

Usage:
```svelte
<script>
  import { currentUser } from '$lib/stores/user'
</script>

{#if $currentUser}
  <p>Welcome, {$currentUser.name}!</p>
{:else}
  <p>Please log in</p>
{/if}
```

## Best Practices

1. **Routing:**
   - Use file-based routing
   - Implement layouts for shared UI
   - Use `+page.js` for data loading
   - Use `+page.server.js` for server-only code

2. **Data Loading:**
   - Load data in `load` functions
   - Handle errors gracefully
   - Show loading states

3. **Forms:**
   - Use SvelteKit form actions
   - Use `enhance` for progressive enhancement
   - Validate on client and server

4. **Components:**
   - Keep components small and focused
   - Use props for configuration
   - Use slots for composition
   - Colocate styles with components

5. **API Communication:**
   - Use Eden Treaty for type-safe API calls
   - Centralize API client logic
   - Handle errors consistently

6. **Performance:**
   - Use SSR by default
   - Preload data for better UX
   - Lazy load heavy components
   - Optimize images

## Common Patterns

**Loading state:**
```svelte
<script>
  import { onMount } from 'svelte'
  
  let loading = true
  let data = []

  onMount(async () => {
    try {
      data = await fetchData()
    } finally {
      loading = false
    }
  })
</script>

{#if loading}
  <p>Loading...</p>
{:else}
  <!-- Show data -->
{/if}
```

**Conditional rendering:**
```svelte
{#if condition}
  <p>True</p>
{:else if otherCondition}
  <p>Other</p>
{:else}
  <p>False</p>
{/if}
```

**Lists:**
```svelte
{#each items as item (item.id)}
  <div>{item.name}</div>
{/each}
```

## References

- [SvelteKit Documentation](https://kit.svelte.dev/)
- [Svelte Tutorial](https://svelte.dev/tutorial)
- [Eden Treaty Documentation](https://elysiajs.com/eden/overview.html)

Related Skills

sveltekit-latest

16
from diegosouzapw/awesome-omni-skill

Quick-reference for SvelteKit + Svelte 5 development (Feb 2026)

form-and-actions-in-sveltekit

16
from diegosouzapw/awesome-omni-skill

Describes Form and Actions implementations.

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

swift-human-guidelines

16
from diegosouzapw/awesome-omni-skill

Comprehensive Swift 6 and SwiftUI development guidelines for building iOS 26, iOS 18, iPadOS, macOS, watchOS, visionOS, and tvOS applications. Covers Foundation Models API, BGContinuedProcessingTask, Call Translation API, Liquid Glass design system, data-race safety, typed throws, synchronization primitives, SwiftUI/UIKit interoperability, zoom transitions, and document-based apps. Use when building new Apple platform apps, implementing Apple Intelligence features, optimizing performance with Swift 6 concurrency, following Apple Human Interface Guidelines, creating cross-platform applications, or working with iOS 26/18 APIs. Triggers on Swift code, SwiftUI views, Xcode projects, app architecture, background processing, translation features, Foundation Models, synchronization, actors, Sendable types, or modern Apple platform development.

swift-conventions

16
from diegosouzapw/awesome-omni-skill

Swift coding conventions and best practices for modern Swift development. Use when writing, reviewing, or refactoring Swift code to ensure consistency with naming conventions, access control, async/await patterns, and SwiftUI/framework best practices.

swift-concurrency

16
from diegosouzapw/awesome-omni-skill

Expert guidance on Swift Concurrency best practices, patterns, and implementation. Use when developers mention: (1) Swift Concurrency, async/await, actors, or tasks, (2) "use Swift Concurrency" or "modern concurrency patterns", (3) migrating to Swift 6, (4) data races or thread safety issues, (5) refactoring closures to async/await, (6) @MainActor, Sendable, or actor isolation, (7) concurrent code architecture or performance optimization, (8) concurrency-related linter warnings (SwiftLint or similar; e.g. async_without_await, Sendable/actor isolation/MainActor lint).

swedish-medications

16
from diegosouzapw/awesome-omni-skill

Look up Swedish medication information from FASS (Farmaceutiska Specialiteter i Sverige). Use when users ask about medications, drugs, läkemedel, dosages, side effects (biverkningar), interactions, or need to understand prescriptions in Sweden. Covers all medications approved for use in Sweden.

swe-programming-elixir-phoenix

16
from diegosouzapw/awesome-omni-skill

Phoenix Framework coding standards from authoritative docs/explanation/software-engineering/platform-web/tools/elixir-phoenix/ documentation

sw-tech-stack-planner

16
from diegosouzapw/awesome-omni-skill

Use when user wants a tech stack recommendation, technology choices, docker-compose setup, or architecture decisions for a software project – reads vision.md, user-stories.md, use-cases.md and generates requirements/tech-stack.yaml silently.

svelte-remote-functions

16
from diegosouzapw/awesome-omni-skill

Guide for SvelteKit Remote Functions. Use this skill by default for all SvelteKit projects doing type-safe client-server communication with query (data fetching), form (progressive enhancement), command (imperative actions), or data invalidation/refresh patterns.

surrealdb-ffi-codec

16
from diegosouzapw/awesome-omni-skill

A codec implementation pattern for high‑efficiency FFI data exchange between SurrealDB Embedded and Go/Swift/other languages, eliminating JSON by using FlatBuffers + MessagePack. Used for Rust FFI layer construction, SurrealDB query result conversion, and binary serialization.

superpowers-writing-skills

16
from diegosouzapw/awesome-omni-skill

Use when creating new skills, editing existing skills, or verifying skills work before deployment