Opinionated design system for Svelte with Tailwind CSS
📦 Installation
# Create Vite + Svelte project
npm create vite@latest my-app -- --template svelte-ts
cd my-app
# Install dependencies
npm install @skeletonlabs/skeleton @skeletonlabs/skeleton-svelte
npm install -D tailwindcss @tailwindcss/vite⚙️ Configuration
vite.config.ts
import { defineConfig } from "vite"
import { svelte } from "@sveltejs/vite-plugin-svelte"
import tailwindcss from "@tailwindcss/vite"
export default defineConfig({
plugins: [
tailwindcss(), // ⚠️ MUST come BEFORE svelte
svelte(),
],
})src/app.css
@import "tailwindcss";
@import "@skeletonlabs/skeleton";
@import "@skeletonlabs/skeleton/themes/skeleton";index.html
<body data-theme="skeleton"></body>🎨 Presets (Button/Card Styling)
| Pattern | Example | Use Case |
|---|---|---|
preset-filled-{color}-{shade} | preset-filled-primary-500 | Solid background |
preset-tonal-{color} | preset-tonal-secondary | Muted/subtle |
preset-outlined-{color}-{shade} | preset-outlined-tertiary-500 | Border only |
preset-gradient-* | Custom gradient | Gradient fills |
Colors
primary · secondary · tertiary · success · warning · error · surface
Shades
50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 · 950
🧩 Core Classes
Buttons
<button class="btn preset-filled-primary-500">Primary</button>
<button class="btn preset-tonal-secondary">Subtle</button>
<button class="btn preset-outlined-error-500">Danger</button>
<button class="btn-icon preset-filled-surface-500">🔔</button>Cards
<div class="card preset-filled-surface-100-900 p-4">
<h3 class="h3">Card Title</h3>
<p>Card content</p>
</div>
<div class="card p-4 preset-tonal-primary">Tonal Card</div>
<div class="card p-4 preset-outlined-secondary-500">Outlined</div>Typography
<h1 class="h1">Heading 1</h1>
<h2 class="h2">Heading 2</h2>
<h3 class="h3">Heading 3</h3>
<h4 class="h4">Heading 4</h4>
<p class="text-surface-600-300-token">Muted text</p>🔮 Svelte 5 Runes + Skeleton
Counter Example
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
</script>
<div class="card preset-filled-surface-100-900 p-6 text-center">
<p class="text-4xl font-bold text-primary-500">{count}</p>
<p class="text-sm text-surface-500">Doubled: {doubled}</p>
<div class="flex gap-4 justify-center mt-4">
<button class="btn preset-filled-primary-500" onclick={() => count++}>
+1
</button>
<button class="btn preset-outlined-secondary-500" onclick={() => count = 0}>
Reset
</button>
</div>
</div>State in .svelte.ts modules
// src/state/counter.svelte.ts
export const counter = $state({ count: 0 })
export function increment() {
counter.count++
}🎭 Themes
Built-in Themes
@import "@skeletonlabs/skeleton/themes/skeleton";
@import "@skeletonlabs/skeleton/themes/wintry";
@import "@skeletonlabs/skeleton/themes/modern";
@import "@skeletonlabs/skeleton/themes/hamlindigo";
@import "@skeletonlabs/skeleton/themes/rocket";
@import "@skeletonlabs/skeleton/themes/sahara";
@import "@skeletonlabs/skeleton/themes/seafoam";
@import "@skeletonlabs/skeleton/themes/vintage";
@import "@skeletonlabs/skeleton/themes/crimson";
@import "@skeletonlabs/skeleton/themes/gold-nouveau";Theme Switching
<body data-theme="wintry"></body><script>
function setTheme(name: string) {
document.body.dataset.theme = name;
}
</script>📐 Layout Helpers
<!-- Container -->
<div class="container mx-auto p-4">
<!-- Grid -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<!-- Flex -->
<div class="flex items-center justify-between gap-4">
<!-- Space-Y -->
<div class="space-y-4">🔗 Resources
| Resource | URL |
|---|---|
| 📚 Docs | https://skeleton.dev/docs/svelte |
| 🎨 Themes | https://skeleton.dev/docs/svelte/design/themes |
| 🧩 Components | https://skeleton.dev/docs/svelte/framework-components |
| 📦 npm skeleton | https://www.npmjs.com/package/@skeletonlabs/skeleton |
| 📦 npm svelte | https://www.npmjs.com/package/@skeletonlabs/skeleton-svelte |
⚡ Quick Reference
| Need | Solution |
|---|---|
| Solid button | btn preset-filled-primary-500 |
| Subtle button | btn preset-tonal-secondary |
| Outlined button | btn preset-outlined-error-500 |
| Card | card preset-filled-surface-100-900 p-4 |
| Heading | h1, h2, h3, h4 |
| Muted text | text-surface-600-300-token |
| Primary color | text-primary-500 |
| Icon button | btn-icon preset-filled-surface-500 |
Created: Dec 2024 | Skeleton v2.10+ | Svelte 5 | Tailwind 4