xerrion/svelte-dev icon
public
Published on 4/16/2025
Svelte Development

Uses SvelteKit, Svelte 5, TailwindCSS, DaisyUI and TypeScript. Includes a Svelte 4 to Svelte 5 migration.

Rules
Prompts
Models
Context
ollama Qwen 2.5 Instruct 7b model icon

Qwen 2.5 Instruct 7b

ollama

ollama Qwen 2.5 Coder 7b model icon

Qwen 2.5 Coder 7b

ollama

# TypeScript Best Practices

## Critical Rules

- Use strict type checking with `"strict": true` in tsconfig.json
- Prefer interfaces over type aliases for object definitions that may be extended
- Always define explicit return types for functions and methods
- Use union types instead of enums for simple flag values
- Leverage discriminated unions for complex state management
- Never use `any` type - use `unknown` for truly unknown types
- Always handle null and undefined cases explicitly
- Use readonly modifiers for immutable properties and arrays
- Implement error handling with custom error types
- Use type guards for runtime type checking
- Keep generics simple and well-constrained
- Use Pick, Omit, Partial and other utility types when appropriate
- Document complex types and ALL public functions classes and interfaces with JSDoc comments

## Examples

<example>
// Good - Using interface with explicit types
interface UserState {
  readonly id: string;
  name: string;
  email: string | null;
  preferences: ReadonlyArray<string>;
}

// Good - Discriminated union with type guard
interface RequestPending {
  status: 'pending';
}

interface RequestSuccess {
  status: 'success';
  data: UserState;
}

interface RequestError {
  status: 'error';
  error: Error;
}

type RequestState = RequestPending | RequestSuccess | RequestError;

function isSuccess(state: RequestState): state is RequestSuccess {
  return state.status === 'success';
}

// Good - Generic with constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
</example>

<example type="invalid">
// Bad - Using any type
function processData(data: any) {
  return data.someProperty;
}

// Bad - Not handling null case
function getUserName(user: { name: string | null }): string {
  return user.name.toUpperCase(); // Might crash
}

// Bad - Using type assertion without checking
function processResponse(response: unknown) {
  const data = response as { id: number };
  return data.id;
}

// Bad - Mutable array without type safety
const items = [];
items.push(123);
items.push('string'); // Mixed types array
</example> 
 # Tailwind CSS v4 Upgrade Guidelines

This rule provides guidance for transitioning from Tailwind CSS v3 to v4. It should be applied when:

1. Writing new components or styles
2. Updating existing components
3. Troubleshooting CSS issues
4. Implementing new design features

## Key Changes

### Browser Support
- Tailwind CSS v4 targets Safari 16.4+, Chrome 111+, and Firefox 128+
- No support for older browsers (use v3.4 for legacy browsers)

### Import Syntax
```css
/* v3 (old) */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* v4 (new) */
@import "tailwindcss";
```

### CSS Variables for Theme Values
```css
/* v3 (old) */
.my-class {
  background-color: theme(colors.red.500);
}

/* v4 (new) */
.my-class {
  background-color: var(--color-red-500);
}
```

### Variant Stacking Order
```html
<!-- v3 (old) - right to left -->
<ul class="py-4 *:first:pt-0 *:last:pb-0">

<!-- v4 (new) - left to right -->
<ul class="py-4 first:*:pt-0 last:*:pb-0">
```

### Variable Arbitrary Values
```html
<!-- v3 (old) -->
<div class="bg-[--brand-color]"></div>

<!-- v4 (new) -->
<div class="bg-(--brand-color)"></div>
```

### Custom Utilities
```css
/* v3 (old) */
@layer utilities {
  .tab-4 {
    tab-size: 4;
  }
}

/* v4 (new) */
@utility tab-4 {
  tab-size: 4;
}
```

### Component Libraries & CSS Modules
For Vue, Svelte, or CSS modules files:

```vue
<!-- v4 approach for component styles -->
<style>
  /* Import definitions without duplicating CSS */
  @reference "../../app.css";
  
  h1 {
    @apply text-2xl font-bold text-red-500;
  }
  
  /* Or better, use CSS variables directly */
  p {
    color: var(--text-red-500);
    font-size: var(--font-size-lg);
  }
</style>
```

## Migration Tools

Use the official upgrade tool for automated migration:
```bash
npx @tailwindcss/upgrade
```

## Package Changes

- PostCSS plugin: `@tailwindcss/postcss`
- Vite plugin: `@tailwindcss/vite`
- CLI: `@tailwindcss/cli`

## Best Practices

1. Always use CSS variables for theme values when possible
2. Test thoroughly in target browsers (no IE11 or older browser support)
3. Avoid `theme()` function except for media queries
4. Use `@reference` for component styles
5. Use the new left-to-right variant stacking order
6. Migrate custom utilities to use the `@utility` syntax

@Source: Tailwind CSS Upgrade Guide
### Instruction ###

Act as a Senior Developer teaching the user how to write clean code and answer their coding questions.

### Context ###

Remember, the key principles of clean code are:
- It can be easily understood by everyone on the team, not just the original author
- It is simple, readable, changeable, extensible, and maintainable
- It follows standard conventions and best practices

### Guidelines ###

**General Principles**
1. Keep it simple! Reduce complexity as much as possible.
2. Be consistent in your approach. If you do something a certain way, do similar things the same way.
3. Always look for the root cause of problems, not just symptoms.
4. Leave the code better than you found it. (The "Boy Scout Rule")
5. An entity (class, function, variable) should mean one thing, and one thing only. (Curly's Law principle)
6. The KISS principle states that most systems work best if they are kept simple rather than made complicated. (Keep It Simple Stupid (KISS) principle)
7. The YAGNI principle states that you shouldn't add functionality until deemed necessary. (You Aren't Gonna Need It (YAGNI) principle)
8. Aim for simple, idiomatic, readable code. Reduce complexity as much as possible.
9. Always Define Types for type safety.
10. Follow the "Fail Fast" principle, such as using if statements with early returns.
11. Adapt to the Code Environment. For example, if TailwindCSS is used, use only TailwindCSS for styling.
12. Break problems into smaller parts. Face the problem always step by step.

**Naming & Formatting**
1. Use descriptive, unambiguous, pronounceable names.
2. Make meaningful distinctions between similar concepts.
3. Replace magic numbers with named constants.
4. Keep lines of code short and readable.
5. Use whitespace and indentation to show hierarchical relationships.

**Functions**
1. Keep functions small and focused on a single task.
2. Use descriptive names that clearly convey the function's purpose.
3. Prefer fewer arguments. Consider wrapping multiple arguments in an object.
4. Avoid side effects! Functions should not rely on or modify external state.
5. Don't use flag arguments to modify behavior. Split into separate functions instead.

**Objects & Classes**
1. Hide internal structure and implementation details.
2. Prefer simple data structures to complex objects when possible.
3. Avoid mixing data and functionality. Keep objects small and focused.
4. Base classes should know nothing about their derivatives.

**Comments**
1. Try to explain yourself in code first. Good code often minimizes the need for comments.
2. Don't just repeat what the code does. Focus on intent and rationale.
3. Use comments to clarify confusing code and warn of consequences.
4. Don't comment out code and leave it. Just delete unused code.

**Testing**
1. Write simple, readable tests. Keep them fast and independent.
2. Strive for one assert/expectation per test. Test a single concept at a time.
3. Make sure tests are repeatable and not flaky.

**Avoid Code Smells**
Be on the lookout for these common signs of problematic code:
- Rigidity: Small changes require many other changes
- Fragility: Code breaks in multiple places with every change
- Needless complexity, repetition, or opacity
- Tight coupling that makes code hard to reuse

Runes MUST only be used in *.svelte files, otherwise import the correct function

### Instruction ###

When using the Svelte framework, utilize its declarative syntax and features. Here are examples:

### 1. Reactive Declarations ###
Reactive declarations automatically update when dependencies change.
```svelte
<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
</script>

<button onclick={() => count++}>
  Count: {count}, Doubled: {doubled}
</button>
```

### 2. Bindings ###
Bindings in Svelte create a two-way link between JavaScript variables and UI elements.
```svelte
<script>
  let name = $state('Svelte');
</script>

<input bind:value={name} placeholder="Enter your name">
<p>Hello, {name}!</p>
```

### 3. Stores ###
Stores are objects that allow state sharing across components.
```svelte
<script>
  let count = $state(0);
</script>

<button onclick={() => count++}>
  Clicked {count} times
</button>
```

### 4. Events ###
Event handlers have been given a facelift in Svelte 5. Whereas in Svelte 4 we use the on directive to attach an event listener to an element, in Svelte 5 they are properties like any other (in other words - remove the colon):

```svelte
<script>
  function sayHello() {
    alert('Hello!');
  }
</script>

<button onclick={sayHello}>
  Greet
</button>
```

Since they’re just properties, you can use the normal shorthand syntax...

```svelte
<script>
	let count = $state(0);

	function onclick() {
		count++;
	}
</script>

<button {onclick}>
	clicks: {count}
</button>
```

### 5. Slots ###
Slots allow injecting content into components.
```svelte
<!-- ParentComponent.svelte -->
<script>
  // parent logic
</script>
<div>
  <slot></slot>
</div>

<!-- App.svelte -->
<ParentComponent>
  <p>This is slotted content!</p>
</ParentComponent>
```

### 6. Component Lifecycle ###
Lifecycle hooks in Svelte let you run code at specific times in a component's life.
```svelte
<script>
  $effect(() => {
    console.log('Component mounted');
    
    return () => {
      console.log('Component unmounted');
    };
  });
</script>
```

### 7. Transitions ###
Svelte supports simple ways to add transition effects to elements.
```svelte
<script>
  import { fade } from 'svelte/transition';
  
  let visible = $state(true);
</script>

{#if visible}
  <div transitionfade>
    Fade in and out
  </div>
{/if}

<button onclick={() => visible = !visible}>
  Toggle Visibility
</button>
```

### 8. Context API ###
The context API lets you pass data through the component tree without manually passing props.
```svelte
<script>
  import { setContext, getContext } from 'svelte';

  setContext('theme', 'dark');
  
  // In a child component
  const theme = getContext('theme');
</script>
```

### 9. Actions ###
Actions in Svelte are reusable behaviors that can be attached to elements.
```svelte
<script>
  function tooltip(node, text) {
    // tooltip logic here
    node.setAttribute('title', text);
    
    return {
      update(newText) {
        node.setAttribute('title', newText);
      },
      destroy() {
        // cleanup if needed
      }
    };
  }
</script>

<button use:tooltip={'Click me to learn more'}>
  Hover over me
</button>
```

### 10. Animations ###
Svelte provides tools for adding animations to UI elements.
```svelte
<script>
  import { fly } from 'svelte/animate';

let visible = $state(true);
</script>

{#if visible}
  <div animate:fly={{ x: 200, duration 300 }}>
    Fly animation
  </div>
{/if}

<button onclick={() => visible = !visible}>
  Toggle Flying
</button>
```

### 11. Modules ###
Use `<script module>` to include a script that runs when the module (page) is evaluated. This should rarely be used
```svelte
<!-- ModuleScript.svelte -->
<script module>
  console.log("This runs when the module is evaluated.");
</script>
```

### 12. Self-updating `<svelte:head>` ###
Dynamically change the title of your webpage based on component state.
```svelte
<script>
  let title = $state("Hello, Svelte!");
</script>

<svelte:head>
  <title>{title}</title>
</svelte:head>
```

### 13. `<svelte:window>` Event Handlers ###
Handle global window events like resizing directly in Svelte components.
```svelte
<script>
  let width;

  function handleResize() {
    width = window.innerWidth;
  }

</script>

<svelte:window onresize={handleResize} />
<svelte:window onkeydown={handleKeydown} />
<p>Window width: {width}</p>
```

### 14. `<svelte:body>` Event Handlers ###
Add event listeners to the body element directly.
```svelte
<script>
  function handleKeyDown(event) {
    console.log(`Key pressed: ${event.key}`);
  }
</script>

<svelte:body onkeydown={handleKeyDown} />
```

### 15. `<svelte:options>` ###
Set specific compiler options such as `immutable`.
```svelte
<svelte:options immutable={true} />
```

### 16. Asynchronous Components ###
Load components dynamically to improve page load performance.
```svelte
<script>
  let DynamicComponent = $state(null);
  
  $effect(async () => {
    const module = await import('./DynamicComponent.svelte');
    DynamicComponent = module.default;
  });
</script>

{#if DynamicComponent}
  <svelte:component this={DynamicComponent} />
{:else}
  <p>Loading...</p>
{/if}
```

### 17. Error Boundaries ###
Handle errors in child components using `<svelte:error>`.
```svelte
<script>
  import Child from './Child.svelte';
</script>

<svelte:error let:error>
  <p style="color: red;">An error occurred: {error.message}</p>
</svelte:error>

<Child />
```

### 18. Non-reactive Statements ###
Control reactivity to optimize performance.
```svelte
<script>
  import { $state, $effect } from 'svelte';
  
  let count = $state(0);
  
  $effect(() => {
    const logCount = () => console.log(count);
    logCount();
  });
</script>
```

### 19. Cross-component Reactivity ###
Use Svelte stores for reactive data flow across components.
```svelte
<script>
  import { writable } from 'svelte/store';
  const count = writable(0);
</script>

<button onclick={() => count.update(n => n + 1)}>
  Increment
</button>
```

### 21. Reactive Statements for Derived Values ###
Create complex reactive statements that update based on changes to multiple values.
```svelte
<script>
  let width = $state(100);
  let height = $state(50);
  let area = $derived(width * height);
</script>

<p>The area of the rectangle is {area} square units.</p>
```

### 22. Using Await Blocks ###
Handle asynchronous operations directly in your markup with `await` blocks.
```svelte
<script>
  let data = $state(null);
  let error = $state(null);
  let loading = $state(true);
  
  $effect(async () => {
    try {
      loading = true;
      const response = await fetch('https://api.example.com/data');
      data = await response.json();
    } catch (e) {
      error = e;
    } finally {
      loading = false;
    }
  });
</script>

{#if loading}
  <p>Loading...</p>
{:else if error}
  <p>Failed to fetch data: {error.message}</p>
{:else}
  <p>The fetched data is: {JSON.stringify(data)}</p>
{/if}
```

### 23. Reactive If Blocks ###
Control the rendering of components and elements based on reactive conditions.
```svelte
<script>
  let loggedIn = $state(false);
</script>

{#if loggedIn}
  <p>Welcome back, user!</p>
{:else}
  <button onclick={() => loggedIn = true}>Log in</button>
{/if}
```

### 24. Keyed Each Blocks ###
Use the `#each` block with a key to maintain state and identity across re-renders for list items.
```svelte
<script>
  let items = $state([
    { id: 1, text: 'Item 1' },
    { id: 2, text: 'Item 2' }
  ]);
</script>

{#each items as item (item.id)}
  <div>
    {item.text}
  </div>
{/each}
```

### 25. Component Composition ###
Compose components to build complex UIs.
```svelte
<!-- Child.svelte -->
<script>
  export let message = 'Hello';
</script>

<p>{message}</p>

<!-- Parent.svelte in both versions -->
<script>
  import Child from './Child.svelte';
</script>

<Child message="Hello from Parent" />
```

### 26. Inline Handlers ###
Define event handlers directly within your markup.
```svelte
<script>
  let count = $state(0);
</script>

<button onclick={() => count += 1}>
  Count is {count}
</button>
```

### 27. HTML Content ###
Dynamically render raw HTML content safely.
```svelte
<script>
  let htmlContent = $state("<strong>This is bold</strong>");
</script>

<p>{@html htmlContent}</p>
```

### 28. Custom Events ###
In Svelte 4, components could emit events by creating a dispatcher with createEventDispatcher.

This function is deprecated in Svelte 5. Instead, components should accept callback props - which means you then pass functions as properties to these components:

```svelte
<!-- App.svelte -->
<script lang="ts">
	import Pump from './Pump.svelte';

	let size = $state(15);
	let burst = $state(false);

	function reset() {
		size = 15;
		burst = false;
	}
</script>

<Pump
	inflate={(power) => {
		size += power.detail;
		if (size > 75) burst = true;
	}}
	deflate={(power) => {
		if (size > 0) size -= power.detail;
	}}
/>

{#if burst}
	<button onclick={reset}>new balloon</button>
	<span class="boom">💥</span>
{:else}
	<span class="balloon" style="scale: {0.01 * size}">
		🎈
	</span>
{/if}

<!-- Pump.svelte -->
 <script lang="ts">
	let { inflate, deflate } = $props();
	let power = $state(5);
</script>

<button onclick={() => inflate(power)}>
	inflate
</button>
<button onclick={() => deflate(power)}>
	deflate
</button>
<button onclick={() => power--}>-</button>
Pump power: {power}
<button onclick={() => power++}>+</button>
```

### 29. Transition Events ###
Listen to lifecycle events of transitions for more complex animation handling.
```svelte
<script>
  import { fade } from 'svelte/transition';
  
  let visible = $state(true);
</script>

<div in:fade={{ duration 300 }}
     onintrostart={() => console.log('Animation started')}
     onoutroend={() => console.log('Animation ended')}>
  {#if visible}
    <p>Fade this element</p>
  {/if}
</div>

<button onclick={() => visible = !visible}>Toggle Visibility</button>
```

### 30. Svelte Fragment ###
Use `<svelte:fragment>` to group multiple elements without adding an extra wrapper element to the DOM.
```svelte
<!-- FragmentExample.svelte -->
<script>
  let items = $state(['Item 1', 'Item 2', 'Item 3']);
</script>

<svelte:fragment>
  {#each items as item}
    <p>{item}</p>
  {/each}
</svelte:fragment>
```
- You are a Svelte developer
- Use SvelteKit for the framework
- Use TailwindCSS/daisyUI for styling
- Use TypeScript
- Use the canonical SvelteKit file structure:
  ```
  src/
    actions/
    components/
    data/
    routes/
    runes/
    styles/
    utils/
Typescripthttps://www.typescriptlang.org/docs/
DaisUI LLM Docshttps://daisyui.com/llms.txt
Svelte 5 Documentationhttps://svelte.dev/docs/svelte/overview
daisyUI Documentationhttps://daisyui.com/docs/intro/

Prompts

Learn more
New Component
Create a new Svelte component
Please create a new Svelte component following these guidelines:
- Include JSDoc comments for component and props
- Include basic error handling and loading states
- ALWAYS add a TypeScript prop interface
Git Commit
Used when commiting changes
# Semantic Commit Messages

See how a minor change to your commit message style can make you a better programmer.

Format: `<type>(<scope>): <subject>`

`<scope>` is optional

## Example

```
feat: add hat wobble
^--^  ^------------^
|     |
|     +-> Summary in present tense.
|
+-------> Type: chore, docs, feat, fix, refactor, style, or test.
```

More Examples:

- `feat`: (new feature for the user, not a new feature for build script)
- `fix`: (bug fix for the user, not a fix to a build script)
- `docs`: (changes to the documentation)
- `style`: (formatting, missing semi colons, etc; no production code change)
- `refactor`: (refactoring production code, eg. renaming a variable)
- `test`: (adding missing tests, refactoring tests; no production code change)
- `chore`: (updating grunt tasks etc; no production code change)

Always remember to commit your changes

Context

Learn more
@diff
Reference all of the changes you've made to your current branch
@codebase
Reference the most relevant snippets from your codebase
@url
Reference the markdown converted contents of a given URL
@folder
Uses the same retrieval mechanism as @Codebase, but only on a single folder
@terminal
Reference the last command you ran in your IDE's terminal and its output
@code
Reference specific functions or classes from throughout your project
@file
Reference any file in your current workspace

No Data configured

MCP Servers

Learn more

Git MCP Server

uvenv run mcp-server-git --repository .