← headroom.walls.sh

Claude Code for Svelte and SvelteKit

Svelte's compiler-first model and SvelteKit's file-system routing are a good fit for Claude Code — the conventions are consistent enough that generating correct components and routes is reliable. This page covers the patterns that save the most time.

CLAUDE.md for a SvelteKit project

# SvelteKit App

## Stack
- SvelteKit + TypeScript + Vite
- Styling: Tailwind CSS
- State: Svelte stores (writable/derived/readable)
- Data fetching: SvelteKit load functions
- Testing: Vitest + Svelte Testing Library + Playwright

## Commands
- Dev: npm run dev
- Test: npm test
- E2E: npx playwright test
- Typecheck: npx svelte-check --tsconfig ./tsconfig.json
- Build: npm run build

## Conventions
- Components in src/lib/components/ — PascalCase .svelte files
- Stores in src/lib/stores/ — one store per domain
- Types in src/lib/types/ — shared TypeScript interfaces
- SvelteKit routes in src/routes/ — +page.svelte, +page.ts, +layout.svelte
- No inline styles — use Tailwind classes

Generate a Svelte component

claude "create a TagInput.svelte component: takes an array of tags (strings) as a prop, lets the user add tags by typing and pressing Enter, remove tags by clicking X. Dispatch a 'change' event with the updated array. Follow patterns in src/lib/components/."

Claude Code reads your existing components to match the script/template/style structure you use — script ordering, TypeScript style, event dispatch patterns. It won't invent a different structure.

SvelteKit load functions and routing

claude "add a /blog/[slug] route. The +page.ts load function fetches the post from the CMS API using the slug parameter. Return the post data and a 404 error if not found. The +page.svelte renders the title, date, and HTML content. Add basic meta tags for SEO."

SvelteKit's load function pattern is well-understood by Claude Code — it generates the correct PageLoad type, error() helper for the 404, and wires the data type to the page component automatically.

Svelte stores

claude "create a cartStore in src/lib/stores/cart.ts. It should be a writable store with: items (array of {product, quantity}), addItem, removeItem, updateQuantity, and a derived totalPrice store. Export all of them. Persist to localStorage on change."

Derived stores and persistence are a common pattern Claude Code handles well. Specify the shape of the items upfront — it will use that interface consistently across the store and all consumers.

claude "read src/routes/checkout/+page.svelte and migrate it to use cartStore instead of the local state it currently uses. Keep all UI behavior identical."

SvelteKit API routes (+server.ts)

claude "add a POST /api/subscribe +server.ts route. Accept { email } in the request body, validate with Zod (valid email required), add to the mailing list via the Mailchimp API (key in MAILCHIMP_API_KEY env), return { success: true } or a 400/500 error. Write a test."

Claude Code generates the RequestHandler type, the Zod schema, error responses, and the test — all in the SvelteKit idiom.

Svelte transitions and animations

claude "add a fade transition to the notification toast component when it appears and disappears. Use Svelte's built-in fade transition. The duration should be 200ms. Follow the existing animation patterns in the codebase if any."
claude "add a slide-in animation to the mobile menu — slides in from the left when open, slides back out when closed. Use Svelte's fly transition."

TypeScript migration

claude "add TypeScript to all .svelte files in src/lib/components/ that are using JavaScript. Add prop types with TypeScript. Use `lang="ts"` in the script block. Run svelte-check after each file."

The svelte-check command is the right verifier for Svelte TypeScript — it catches both TypeScript errors and Svelte-specific issues that tsc alone would miss.

Write component tests

claude "write Vitest + Svelte Testing Library tests for TagInput.svelte. Cover: renders with initial tags, adds tag on Enter, removes tag on X click, does not add empty tags, dispatches change event with updated array."
claude "run the tests and fix any failures: npm test -- TagInput"

The two-step pattern — write, then run-and-fix — works better than asking for working tests upfront. The actual test runner output tells Claude Code exactly what to fix.

Playwright end-to-end tests

claude "write Playwright tests for the cart flow: add item to cart from product page, verify cart badge updates, open cart drawer, update quantity, remove item, proceed to checkout. Use the page object pattern."

SvelteKit form actions

claude "convert the contact form from a fetch-based submission to a SvelteKit form action. Create a +page.server.ts with a default action that validates the fields with Zod, sends the email, and returns success or field-level errors. Update the +page.svelte to use enhance() and show the errors inline."

Form actions with progressive enhancement are idiomatic SvelteKit — Claude Code generates the correct Actions type, fail() for validation errors, and the ActionData type for the page.

SvelteKit hooks and middleware

claude "add a src/hooks.server.ts handle function that checks for a session cookie on protected routes (anything under /dashboard). Redirect to /login if there's no valid session. Pass the session data to the event.locals so load functions can access it."

Monitor session budget during Svelte work

SvelteKit's type system (svelte-check) can produce cascading errors when a store shape or load function return type changes — fixing them iteratively burns session budget faster than it looks.

Headroom — watch your session budget while the type checker runs

When Claude Code is iterating on Svelte component types or running a test loop, your 5-hour session meter is moving. Headroom shows your Claude Code session (5h) and weekly (7d) utilization live in the macOS menu bar — color-coded from calm to amber to red. No token, no API key: it reads the file Claude Code writes to ~/.claude/.

Install in one line:

brew install patwalls/tap/headroom

Check the menu bar before starting a large svelte-check fix loop — you'll know if you have the headroom to finish it.

Common Svelte + Claude Code patterns

TaskPrompt pattern
New componentcreate a [Name].svelte component: [spec]. Follow patterns in src/lib/components/
New routeadd a /[path] route with load function and page component. Fetch [data] from [source].
New storecreate a [name]Store with: [shape]. Derived stores for [computed values]. Persist to localStorage.
Add testswrite STL tests for [Component]. Cover: [cases]. Run: npm test -- [Component]
Form actionconvert [form] to a SvelteKit form action with Zod validation and inline errors.

Claude Code for TypeScript
Claude Code for React
Writing tests with Claude Code
Claude Code + VS Code