DEV Community

Olivia Craft
Olivia Craft

Posted on

CLAUDE.md for SvelteKit: 13 Rules That Stop AI from Treating It Like React

SvelteKit has its own mental model for routing, data loading, and reactivity. It's not React. It's not Next.js. AI tools that treat it like React produce code that compiles but fights the framework at every turn.

The failure modes are predictable: useEffect where a load function belongs, fetch in components where form actions should handle mutations, React hook patterns in Svelte component logic, useState where Svelte's reactive declarations work better.

A CLAUDE.md file at the repo root fixes this by declaring the SvelteKit model upfront. Here are 13 rules that cover the most common drift patterns.


Rule 1: This is SvelteKit, not React

This project uses SvelteKit with Svelte 5.
Do NOT generate React patterns:
- No useState, useEffect, useRef, useContext
- No JSX syntax
- No React component lifecycle methods
- No react-router or react-query
Use Svelte's reactivity model and SvelteKit's conventions.
Enter fullscreen mode Exit fullscreen mode

Rule 2: Load functions own server-side data fetching

Data fetching for routes lives in +page.server.ts (server) or
+page.ts (universal) load functions.
Do NOT fetch data in onMount or component-level code
when a load function can handle it.
Access load data via the data prop: export let data.
Enter fullscreen mode Exit fullscreen mode

Rule 3: Form actions own all mutations

Form submissions and data mutations use SvelteKit form actions
defined in +page.server.ts.
Use the enhance action for progressive enhancement.
Do NOT use fetch() in components for mutations that a form
action can handle.
Enter fullscreen mode Exit fullscreen mode

Rule 4: File-system routing conventions

+page.svelte: the page UI
+page.server.ts: server-only load + actions
+page.ts: universal load (runs on server + client)
+layout.svelte: shared UI for a route segment
+layout.server.ts: shared server data for a segment
+error.svelte: error page for a segment
+server.ts: API endpoint (GET, POST, etc.)
Do not put server logic in +page.svelte or +page.ts.
Enter fullscreen mode Exit fullscreen mode

Rule 5: Svelte 5 reactivity uses runes

This project uses Svelte 5 runes syntax:
  $state() for reactive state
  $derived() for computed values
  $effect() for side effects (use sparingly)
  $props() for component props
Do NOT use Svelte 4 reactive declarations ($:) unless
the project explicitly uses Svelte 4 compatibility mode.
Enter fullscreen mode Exit fullscreen mode

Rule 6: Stores for cross-component state

Shared state uses Svelte stores (writable, readable, derived)
imported from svelte/store.
Do NOT use React Context, Redux, or Zustand.
For server-side shared state: use locals in handle hooks.
Enter fullscreen mode Exit fullscreen mode

Rule 7: Transitions and animations use Svelte built-ins

Animations: svelte/transition, svelte/animate, svelte/motion
Do NOT use Framer Motion, React Spring, or CSS-in-JS libraries.
Use Svelte's directive syntax: transition:fade, in:fly, etc.
Enter fullscreen mode Exit fullscreen mode

Rule 8: Environment variables use $env modules

Private server vars: import from '$env/static/private'
Public vars: import from '$env/static/public'
Dynamic vars: '$env/dynamic/private' or '$env/dynamic/public'
Do NOT use process.env directly in SvelteKit code.
Do NOT expose private env vars in +page.ts or +page.svelte.
Enter fullscreen mode Exit fullscreen mode

Rule 9: Path aliases use $lib

Shared code lives in src/lib/ and is imported via '$lib/...'
Do NOT use relative imports like '../../../lib/...'
Components: '$lib/components/Button.svelte'
Utilities: '$lib/utils/format.ts'
Enter fullscreen mode Exit fullscreen mode

Rule 10: API endpoints use +server.ts files

HTTP endpoints: src/routes/api/[path]/+server.ts
Export named functions: GET, POST, PUT, DELETE, PATCH
Return Response objects or use json() helper from @sveltejs/kit
Do NOT create a separate Express server for API routes.
Enter fullscreen mode Exit fullscreen mode

Rule 11: Error handling uses SvelteKit conventions

Expected errors: error() from '@sveltejs/kit' in load/actions
Unexpected errors: handled by +error.svelte
Do NOT use try/catch to swallow errors in load functions throw the error() helper and let SvelteKit handle routing.
Enter fullscreen mode Exit fullscreen mode

Rule 12: SSR and hydration are opt-in/opt-out

SSR is enabled by default. To configure:
  export const ssr = false; // disable SSR for a route
  export const prerender = true; // static generation
  export const csr = false; // disable client-side rendering
Do NOT replicate SSR/hydration logic manually.
Enter fullscreen mode Exit fullscreen mode

Rule 13: Component props use $props() in Svelte 5

Define props at the top of the script block:
  let { title, count = 0, onchange }: { title: "string; count?: number; onchange?: () => void } = $props();"
Do NOT use export let for Svelte 5 components.
Do NOT use React prop patterns (defaultProps, PropTypes).
Enter fullscreen mode Exit fullscreen mode

The full CLAUDE.md block

# SvelteKit Project Rules (Svelte 5)

## Framework
- SvelteKit + Svelte 5 — NOT React or Next.js
- No React hooks, JSX, or React lifecycle patterns

## Routing (file-system)
- +page.svelte: UI
- +page.server.ts: server load + actions
- +page.ts: universal load
- +layout.svelte/.server.ts: shared segments
- +server.ts: API endpoints
- +error.svelte: error pages

## Data & Mutations
- Server data: load functions in +page.server.ts
- Mutations: form actions in +page.server.ts
- No fetch() in components for server mutations

## Svelte 5 Reactivity
- $state(), $derived(), $effect(), $props()
- No Svelte 4 $: reactive declarations

## State
- Cross-component: Svelte stores (svelte/store)
- No React Context, Redux, Zustand

## Environment
- Private: $env/static/private
- Public: $env/static/public
- No process.env in SvelteKit modules

## Paths
- $lib/... for shared code (not relative imports)

## SSR
- SSR on by default
- export const ssr/prerender/csr to configure
Enter fullscreen mode Exit fullscreen mode

Why SvelteKit AI drift is common

The web is full of React tutorials. SvelteKit has a much smaller training footprint. When AI generates "a web framework component with data fetching," it defaults to React patterns because that's what it has seen most.

SvelteKit's conventions are fundamentally different from React in three ways: the reactivity model (compiler-based vs. hook-based), the data layer (file-system load functions vs. useQuery), and the mutation pattern (form actions vs. onClick + fetch).

The CLAUDE.md file tells the AI which paradigm you're working in. Without it, it guesses — and it guesses React.


These 13 rules are part of a framework-specific CLAUDE.md series. The Cursor Rules Pack equivalent (50 production-tested rules across all stacks) is available at oliviacraftlat.gumroad.com/l/wyaeil — search "Olivia Craft Cursor Rules" on Gumroad.

Top comments (0)