Expert guidance for SvelteKit + TypeScript projects with API integration, auth patterns, and Tailwind styling
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 60/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
You are an expert assistant for SvelteKit projects, specializing in Svelte 5 with runes, TypeScript, Tailwind CSS v4, and API integration patterns.
This skill is designed for a SvelteKit frontend application with:
When the user asks to start development or run the app:
```bash
npm run dev
```
This starts the dev server at `http://localhost:5173`. The Vite config proxies `/api` requests to the backend at `localhost:8000`.
Before committing changes or when debugging type issues:
```bash
npm run check
```
```bash
npm run build
npm run preview # Preview the production build
```
**Location**: `src/lib/api/client.ts`
All API requests MUST go through the centralized client which:
**Example Usage**:
```typescript
import { apiClient } from '$lib/api/client';
// GET request
const movies = await apiClient('/api/movies/search?query=inception');
// POST request
const week = await apiClient('/api/weeks', {
method: 'POST',
body: { year: 2025, week_number: 1 }
});
```
**Stores**: `src/lib/stores/auth.ts`
1. User logs in via `/api/auth/login` (handled by `auth.ts` API module)
2. JWT token stored in localStorage
3. Auth store provides reactive `$user` and `$token` state
4. Root layout (`+layout.svelte`) guards protected routes
5. On 401, client auto-redirects to `/login`
**Check auth state**:
```typescript
import { user, token } from '$lib/stores/auth';
if ($user) {
// User is authenticated
}
```
```
src/lib/components/
├── ui/ # Primitives: Button, Input, Toast
├── layout/ # Header, navigation
├── movies/ # MovieCard, MovieSlot
├── albums/ # AlbumCard, AlbumSlot
└── weeks/ # WeekCard, WeekHeader, WeekPicker
```
**Pattern**: Components accept typed props, emit custom events using `createEventDispatcher()`, and use Svelte 5 runes for reactivity.
**TMDB Images**: `src/lib/utils/images.ts` provides `getTmdbImageUrl(path, size)`
**MusicBrainz Cover Art**:
**ISO Week System**: `src/lib/utils/dates.ts`
```typescript
import { getISOWeek, formatWeekRange } from '$lib/utils/dates';
const { year, week_number } = getISOWeek(new Date());
const display = formatWeekRange(year, week_number); // "Jan 1 - Jan 7, 2025"
```
Use semantic color names from `app.css` `@theme`:
| Purpose | Class (Light) | Class (Dark) |
|---------|--------------|--------------|
| Background | `bg-cream-50`, `bg-cream-100` | `bg-stone-900`, `bg-stone-800` |
| Text | `text-stone-800` | `text-cream-100` |
| Accent | `text-amber-600`, `bg-amber-600` | `text-amber-500` |
| Success | `text-sage-600` | `text-sage-500` |
| Error | `text-rose-600`, `bg-rose-50` | `text-rose-500` |
| Borders | `border-cream-200` | `border-stone-700` |
1. **Cards**: White background, `border border-cream-200`, `rounded-md` (NO shadows)
2. **Buttons**: `rounded-md`, amber primary, cream secondary, rose danger
3. **Inputs**: `rounded-md`, cream borders, `ring-amber-400` on focus
4. **Hover States**: Border color → `amber-400` for cards, background darken for buttons
5. **Loading Spinners**: `border-amber-600`
6. **Error Alerts**: `bg-rose-50 border-rose-200 text-rose-700`
**Fixed Heights**: MovieSlot and AlbumSlot use `h-36` content height for visual consistency. Movie posters fill full height; album covers (square) are vertically centered.
Automatically applied via `prefers-color-scheme: dark`. Use Tailwind's `dark:` variant:
```svelte
<div class="bg-cream-50 dark:bg-stone-900 text-stone-800 dark:text-cream-100">
```
1. Define types in `src/lib/api/types.ts`
2. Create module in `src/lib/api/` (e.g., `movies.ts`)
3. Use `apiClient` for all requests
4. Export typed functions
**Example**:
```typescript
// src/lib/api/movies.ts
import { apiClient } from './client';
import type { Movie } from './types';
export async function searchMovies(query: string): Promise<Movie[]> {
return apiClient(`/api/movies/search?query=${encodeURIComponent(query)}`);
}
```
1. Create `+page.svelte` in `src/routes/`
2. Use `onMount` for data fetching
3. Handle loading and error states
4. Respect auth requirements (check `$user`)
**Example**:
```svelte
<script lang="ts">
import { onMount } from 'svelte';
import { user } from '$lib/stores/auth';
import { searchMovies } from '$lib/api/movies';
let movies = $state([]);
let loading = $state(true);
onMount(async () => {
if (!$user) return; // Auth guard
try {
movies = await searchMovies('inception');
} catch (err) {
console.error(err);
} finally {
loading = false;
}
});
</script>
{#if loading}
<div class="spinner"></div>
{:else}
<!-- Render movies -->
{/if}
```
1. Create component in appropriate subdirectory
2. Define props using `$props()`
3. Use Svelte 5 runes (`$state`, `$derived`, `$effect`)
4. Follow design system guidelines
**Example**:
```svelte
<script lang="ts">
import type { Movie } from '$lib/api/types';
interface Props {
movie: Movie;
onSelect?: (movie: Movie) => void;
}
let { movie, onSelect }: Props = $props();
</script>
<button
class="border border-cream-200 rounded-md hover:border-amber-400"
onclick={() => onSelect?.(movie)}
>
<img src={getTmdbImageUrl(movie.poster_path, 'w342')} alt={movie.title} />
<h3 class="font-serif text-stone-800 dark:text-cream-100">{movie.title}</h3>
</button>
```
All API errors return `{ detail: "message" }` format. Key status codes:
The API client shows "Unable to connect to server" for:
**Pattern**:
```typescript
try {
const data = await apiClient('/api/weeks/current');
} catch (err) {
if (err.message.includes('Unable to connect')) {
// Show connection error UI
} else {
// Show API error message
}
}
```
1. **Week Uniqueness**: One week per year+week_number globally (409 on duplicate)
2. **Ownership**: Only owner or unclaimed week can be edited
3. **Positions**: 1 and 2 for each media type (409 if occupied)
4. **Date Formats**: ISO 8601 UTC timestamps, ISO date for releases
5. **Rate Limits**: MusicBrainz = 1 req/sec (implement retry), TMDB = 40 req/10s
6. **Connection Handling**: Gracefully handle backend unavailability
Before marking work complete:
**Core Architecture**:
**API Modules**:
**Utilities**:
**Key Components**:
**Routes**:
Always prioritize following established patterns and the design system. When in doubt, check existing components for reference implementations.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/sveltekit-full-stack-development-assistant/raw