# Stitch Svelte Components

> Converts Stitch designs into Svelte 5 / SvelteKit components using the runes API — scoped CSS with custom properties, built-in transitions, TypeScript, dark mode, and accessible markup.

- **Type:** Skill
- **Install:** `agentstack add skill-gabelul-stitch-kit-stitch-svelte-components`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [gabelul](https://agentstack.voostack.com/s/gabelul)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [gabelul](https://github.com/gabelul)
- **Source:** https://github.com/gabelul/stitch-kit/tree/main/skills/stitch-svelte-components
- **Website:** https://booplex.com/projects/stitch-kit-design-intelligence-for-ai-agents

## Install

```sh
agentstack add skill-gabelul-stitch-kit-stitch-svelte-components
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Stitch → Svelte 5 / SvelteKit Components

You are a Svelte 5 engineer. You convert Stitch design screens into idiomatic Svelte components — using the **runes API** (`$state`, `$props`, `$derived`, `$effect`), not the legacy Options API. Components use scoped CSS with custom properties for theming, built-in Svelte transitions for animation, and accessible markup by default.

> **Note:** This is the only Stitch skill that targets Svelte. The official `react-components` skill targets Vite/React. Use this skill when the project uses SvelteKit.

## When to use this skill

Use this skill when:
- The target project uses **SvelteKit** or **Svelte 5** standalone
- You see `.svelte` files, `svelte.config.js`, or `+page.svelte` conventions
- The user mentions `svelte`, `sveltekit`, `$state`, `$props`, or `runes`

## Prerequisites

- Access to the Stitch MCP server
- A Stitch project with at least one generated screen
- Target project uses Svelte 5 (runes enabled) — check `package.json` for `"svelte": "^5"`

## Step 1: Retrieve the Stitch design

1. **Namespace discovery** — Run `list_tools` to find the Stitch MCP prefix. Use it for all subsequent calls.
2. **Fetch screen metadata** — Call `[prefix]:get_screen` to retrieve design JSON.
3. **Download HTML** — Use the reliable downloader:
   ```bash
   bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"
   ```
4. **Visual reference** — Check `screenshot.downloadUrl` before writing code.

## Step 2: SvelteKit file conventions

SvelteKit uses file-based routing. Map Stitch screens to this structure:

```
src/
├── routes/
│   ├── +layout.svelte        ← Persistent shell (nav, footer)
│   ├── +layout.ts            ← Layout load function (optional)
│   ├── +page.svelte          ← Route page component
│   ├── [route]/
│   │   ├── +page.svelte      ← Sub-route page
│   │   └── +page.ts          ← Page load function (server-side data)
├── lib/
│   ├── components/           ← Reusable components
│   │   └── [Name].svelte
│   ├── data/
│   │   └── mockData.ts       ← Decoupled static content
│   └── types/
│       └── index.ts          ← Shared types
static/                       ← Static assets
```

**Key rules:**
- Pages live in `src/routes/` as `+page.svelte`
- Reusable components live in `src/lib/components/`
- Import `$lib/` is an alias for `src/lib/` — always use it

## Step 3: Svelte 5 runes API

**Use runes exclusively.** Never use the old `export let`, `let x = 0` reactive syntax, or `$:` labels.

### Props
```svelte

  interface Props {
    title: string
    description?: string
    onAction?: () => void
  }

  // $props() replaces export let
  const { title, description = 'Default text', onAction }: Props = $props()

```

### Reactive state
```svelte

  // $state() replaces let count = 0
  let count = $state(0)
  let isOpen = $state(false)

  // $derived() replaces $: doubled = count * 2
  const doubled = $derived(count * 2)

  // $effect() replaces onMount / afterUpdate for side effects
  $effect(() => {
    console.log('count changed:', count)
  })

```

### Event handling
```svelte

 count++}>Increment
Custom action
```

## Step 4: Scoped CSS with design tokens

Svelte scopes CSS to the component by default — use this aggressively. Map Stitch colors to custom properties in the `:root` (via `+layout.svelte` or `app.css`) and reference them in each component.

**In `src/app.css` (global):**
```css
:root {
  --color-background: #ffffff;
  --color-surface: #f4f4f5;
  --color-primary: /* dominant color from Stitch design */;
  --color-primary-foreground: #ffffff;
  --color-text: #09090b;
  --color-text-muted: #71717a;
  --color-border: #e4e4e7;
}

[data-theme='dark'] {
  --color-background: #09090b;
  --color-surface: #18181b;
  --color-primary: /* same hue, adjusted for dark bg */;
  --color-primary-foreground: #09090b;
  --color-text: #fafafa;
  --color-text-muted: #a1a1aa;
  --color-border: #27272a;
}
```

**In each component (scoped):**
```svelte

  .card {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-text);
    border-radius: 0.5rem;
    padding: 1.5rem;
  }

  .card:hover {
    /* Scoped — won't leak to parent or children */
    border-color: var(--color-primary);
  }

```

**Dark mode toggle** — Add a `$state` in `+layout.svelte`:
```svelte

  let theme = $state('light')

  function toggleTheme() {
    theme = theme === 'light' ? 'dark' : 'light'
    document.documentElement.setAttribute('data-theme', theme)
  }

  {@render children()}

```

## Step 5: Built-in transitions and animations

Svelte has first-class transition support. Apply these from the Stitch design intent:

```svelte

  import { fade, fly, slide, scale } from 'svelte/transition'
  import { cubicOut } from 'svelte/easing'

  let show = $state(false)

  Content that fades in

{#if isOpen}
  
    Sidebar content
  
{/if}

{#if expanded}
  
    Expandable content
  
{/if}
```

**Always respect reduced motion:**
```svelte

  // Check user preference once
  const prefersReducedMotion = $state(
    typeof window !== 'undefined'
      ? window.matchMedia('(prefers-reduced-motion: reduce)').matches
      : false
  )

  // Conditionally disable transitions
  const transitionOptions = $derived(
    prefersReducedMotion ? {} : { duration: 200 }
  )

...
```

## Step 6: Accessibility in Svelte

Svelte's compiler warns about missing accessibility attributes — treat all compiler warnings as errors.

- **`role` and ARIA**: Add `role` when using non-semantic elements. Always pair with `aria-label` or `aria-labelledby`.
- **`bind:this`**: Use for programmatic focus management (e.g., focus trap in modals).
- **Keyboard handlers**: Any `onclick` handler on a non-interactive element needs `onkeydown`/`onkeyup` too, or use a ``.
- **Screen reader text**: Use `class="sr-only"` (define in app.css) for visually hidden labels.

```svelte

  

  {title}

```

## Step 7: Execution steps

1. **Environment check** — If `node_modules` missing, run `npm install`.
2. **Data layer** — Create `src/lib/data/mockData.ts` from design content.
3. **Component drafting** — Use `resources/component-template.svelte` as base. Replace all instances of `StitchComponent` with the actual component name.
4. **CSS tokens** — Add color tokens to `src/app.css`. If using `stitch-design-system`, import its generated `design-tokens.css` instead.
5. **Wiring** — Update `src/routes/+page.svelte` to import and use the new components. Import from `$lib/components/`.
6. **Quality check** — Run through `resources/architecture-checklist.md`.
7. **Dev verification** — Run `npm run dev`. Toggle dark mode. Test keyboard navigation.

## Troubleshooting

| Issue | Fix |
|-------|-----|
| Runes syntax error | Confirm `svelte: ^5` in `package.json`. Old syntax is invalid in Svelte 5. |
| `$props()` type error | Add `lang="ts"` to `` tag |
| CSS not scoped | Ensure styles are inside `` block, not in a `.css` import |
| Transition not playing | Check `prefers-reduced-motion` isn't causing empty config |
| `$lib` not resolving | Confirm `"paths": {"$lib/*": ["src/lib/*"]}` in `tsconfig.json` |
| Dark mode flicker on load | Read theme from `localStorage` in a synchronous `` script |

## Integration with other skills

- **stitch-design-system** — Run first to generate `design-tokens.css` for the CSS variable foundation.
- **stitch-animate** — Run after for Svelte-specific transition patterns beyond the basics above.
- **stitch-a11y** — Run after for a full accessibility audit when the design has complex UI patterns.

## References

- `resources/component-template.svelte` — Production-ready Svelte 5 component boilerplate
- `resources/architecture-checklist.md` — Pre-ship quality checklist
- `scripts/fetch-stitch.sh` — Reliable GCS HTML downloader

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [gabelul](https://github.com/gabelul)
- **Source:** [gabelul/stitch-kit](https://github.com/gabelul/stitch-kit)
- **License:** Apache-2.0
- **Homepage:** https://booplex.com/projects/stitch-kit-design-intelligence-for-ai-agents

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-gabelul-stitch-kit-stitch-svelte-components
- Seller: https://agentstack.voostack.com/s/gabelul
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
