Components
Every component in SvelteForge Admin is built with Svelte 5's runes API. There
are no legacy export let declarations or $: reactive statements anywhere
in the codebase. Instead, components use $props for inputs, $state for
local reactivity, $derived for computed values, $effect for side
effects, and {@render} for snippet-based composition.
This approach takes full advantage of the Svelte compiler — every rune is compiled away at build time into efficient vanilla JavaScript with no runtime overhead.
shadcn-svelte Foundation
SvelteForge Admin's UI layer is built on shadcn-svelte, a collection of beautifully designed, accessible components built on top of bits-ui headless primitives. Unlike traditional component libraries, shadcn-svelte components are copied into your project — you own the code and can customize it freely.
Where components live
All shadcn-svelte components are installed into src/lib/components/ui/. Each
component has its own directory with an index.ts barrel export.
Important: do not edit directly
If you need to update a shadcn-svelte component to the latest version, re-add it with the CLI rather than editing the files manually:
npx shadcn-svelte@latest add <component-name> This will overwrite the component with the latest version while preserving your theme tokens.
Available UI components
SvelteForge Admin includes the following shadcn-svelte components out of the box:
| Component | Purpose |
|---|---|
| Button | Primary interaction element with multiple variants (default, destructive, outline, secondary, ghost, link) |
| Card | Content container with header, content, and footer sections |
| Dialog | Modal overlay for focused interactions |
| Alert Dialog | Confirmation modals for destructive actions |
| Dropdown Menu | Contextual menu with keyboard navigation |
| Avatar | User profile image with fallback initials |
| Badge | Status indicators and labels |
| Breadcrumb | Navigation trail for page hierarchy |
| Separator | Visual divider between content sections |
| Sidebar | Collapsible navigation sidebar primitives |
| Sonner | Toast notification system |
| Command | Command palette primitives (search + keyboard nav) |
| Popover | Floating content anchored to a trigger |
| Input | Text input with consistent styling |
| Label | Accessible form labels |
| Select | Dropdown select with keyboard support |
| Table | Data tables with header, body, and row components |
| Tabs | Tabbed content navigation |
| Tooltip | Hover-triggered contextual hints |
| Sheet | Slide-in panel from screen edge |
App-Level Components
Built on top of the shadcn-svelte primitives, SvelteForge Admin includes purpose-built Svelte 5 components for the admin dashboard experience. Each one uses the runes API exclusively.
1. App Sidebar
src/lib/components/app-sidebar.svelte
The primary navigation component for the entire application. It provides a collapsible sidebar with grouped navigation links, a user dropdown, and notification count integration.
Structure
- Overview group — Dashboard, Analytics
- Management group — Users, Content, Notifications
- System group — Roles, Database, Settings
User dropdown
The sidebar footer displays the current user's avatar, name, and email. Clicking opens a dropdown menu with:
- Role badge (admin, editor, or viewer) with color coding
- Link to account settings
- Logout action
Notification badge
The Notifications link displays an unread count badge when there are unread notifications. This count is passed as a prop and updates reactively.
Svelte 5 patterns used
$derived— Builds the reactive navigation array so active states update automatically when the URL changes- Built entirely with shadcn-svelte Sidebar primitives (
Sidebar.Content,Sidebar.Group,Sidebar.MenuItem, etc.)
Props
| Prop | Type | Description |
|---|---|---|
user | { name, email, username, role } | Current authenticated user |
notificationCount | number | Unread notification count for badge display |
2. Command Palette
src/lib/components/command-palette.svelte
A keyboard-driven command palette triggered by Cmd+K (macOS) or Ctrl+K (Windows/Linux). It provides instant navigation, search, and quick actions — a power-user feature built on bits-ui Command primitives and the shadcn Dialog.
Three sections
- Navigation — Eight quick-access routes: Dashboard, Users, Content, Analytics, Notifications, Roles, Database, Settings
- Search Results — API-driven search that queries
/api/search?q={query}. Results are type-aware and display contextual icons: user results show a user icon, page results show a document icon, notification results show a bell icon. - Quick Actions — "New Page" (navigates to content creation) and "Toggle Theme"
(calls
toggleMode()from mode-watcher)
Search behavior
Search is debounced at 250ms to prevent excessive API calls. As the user types, the component waits 250ms after the last keystroke before sending the request. Results appear inline below the navigation section.
Svelte 5 patterns used
$state— Tracks the search query string and results array$effect— Implements the debounce timer, automatically cleaning up on dependency changes- Integrates with mode-watcher for the theme toggle quick action
3. Notification Bell
src/lib/components/notification-bell.svelte
A popover-based notification indicator in the top navigation bar. It shows the unread count as a badge and displays the most recent notifications in a dropdown.
Features
- Unread count badge — Displays the count directly. When the count exceeds 9, it shows "9+" to keep the badge compact.
- Last 5 notifications — The popover shows up to 5 unread notifications
- Type-specific styling — Each notification type has its own icon and color:
- Info — Blue icon
- Warning — Yellow icon
- Error — Red icon
- Success — Green icon
- Time-ago display — Shows relative timestamps: "just now", "Xm ago", "Xh ago", "Xd ago"
- Footer link — "View all notifications" links to
/notifications
Props
| Prop | Type | Description |
|---|---|---|
count | number | Total unread notification count |
notifications | Notification[] | Array of recent unread notifications to display in the popover |
4. Theme Toggle
src/lib/components/theme-toggle.svelte
A button that toggles between light and dark mode. It calls toggleMode() from the mode-watcher library.
Visual behavior
The button displays a sun icon in dark mode and a moon icon in light mode, with smooth CSS
transitions between states using rotate and scale transforms.
Critical Svelte 5 note
The theme toggle uses mode.current to read the current theme — this is a Svelte 5 runes object from mode-watcher. Do NOT use $mode (which is the Svelte 4 store syntax). This distinction is critical when working with
mode-watcher in a Svelte 5 / SvelteKit project.
Button style
Rendered as a ghost variant button from shadcn-svelte for a minimal, icon-only appearance.
5. Animated Counter
src/lib/components/animated-counter.svelte
Smoothly animates a number from 0 to a target value, commonly used in dashboard stat cards. The animation runs on mount and whenever the target value changes.
Animation details
- Timing function — easeOutExpo for a natural deceleration curve
- Default duration — 800ms
- Uses
requestAnimationFramefor smooth 60fps animation
Svelte 5 patterns used
The animation is driven by $effect — whenever the value prop changes, the
effect re-runs and starts a new animation from 0 to the new target.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | Target number to animate to |
duration | number | 800 | Animation duration in milliseconds |
format | (n: number) => string | — | Optional custom format function (e.g., for currency or percentages) |
6. Data Table Pagination
src/lib/components/data-table-pagination.svelte
A reusable pagination component used across the Users, Content, and Notifications tables. It provides page navigation and page-size controls with a consistent UI.
Features
- "Showing X-Y of Z" display — Clear indication of which records are visible
- Page size selector — Dropdown with options for 10, 25, or 50 items per page
- Previous/Next navigation — Buttons with disabled states at boundary pages
This component is a great example of SvelteKit reusability — the same component works across multiple routes because it accepts standardized pagination data through props.
7. Delete Confirm Dialog
src/lib/components/delete-confirm-dialog.svelte
An alert dialog for confirming destructive actions like deleting a user or removing content. Built on the shadcn-svelte Alert Dialog primitive.
Implementation details
- Uses a SvelteKit form action with
use:enhancefor progressive enhancement — the delete works even without JavaScript - Cancel and Confirm buttons with the confirm styled as
destructivevariant - The dialog prevents accidental deletions by requiring an explicit confirmation click
8. Role Change Dialog
src/lib/components/role-change-dialog.svelte
A confirmation dialog shown when an admin changes a user's role. It clearly displays the transition being made — for example, "editor" to "admin" — so the admin can verify the change before confirming.
9. User Form Dialog
src/lib/components/user-form-dialog.svelte
A modal dialog for creating and editing users. It serves dual purpose — the same component handles both "create new user" and "edit existing user" workflows.
Form fields
- Name — Full display name
- Email — Email address with validation
- Username — Unique username
- Password — Required for creation, optional for editing
- Role — Select dropdown with admin, editor, and viewer options
Error handling
Server-side validation errors are returned from SvelteKit form actions and displayed inline next to the relevant fields.
10. Apps Menu
src/lib/components/apps-menu.svelte
A quick-access grid menu in the top navigation bar for fast section navigation. It opens as a dropdown with icon + label pairs for each major section of the admin dashboard.
Svelte 5 Reactive Hooks
SvelteForge Admin includes custom reactive utilities that leverage Svelte 5's class-based reactivity pattern.
IsMobile
src/lib/hooks/is-mobile.svelte.ts
A reactive hook class that detects whether the viewport is below a mobile breakpoint (768px). It
extends the MediaQuery class for responsive breakpoint detection.
Usage
<script lang="ts">
import { IsMobile } from "#lib/hooks/is-mobile.svelte.js";
const isMobile = new IsMobile();
</script>
{#if isMobile.current}
<p>Mobile layout</p>
{:else}
<p>Desktop layout</p>
{/if} Because this is a Svelte 5 runes-based class (note the .svelte.ts file extension), the current property is reactive — components re-render automatically
when the viewport crosses the 768px boundary.
The cn() Utility
src/lib/utils.ts
A utility function that combines clsx (conditional class names) with tailwind-merge (deduplicates and resolves conflicting Tailwind classes). It is used throughout the codebase for composing class names:
import { cn } from "#lib/utils.js";
// Merge base classes with conditional and override classes
cn("px-4 py-2 bg-primary", isActive && "bg-primary/90", className);
// tailwind-merge ensures no conflicting classes survive Import it from #lib/utils — this is the standard pattern across all SvelteKit components in the project.
Need More Components?
50+ Pages with DashboardPack Premium
Want Chat, Mail, Kanban boards, Calendar, File Manager, and more? Our premium Svelte-quality templates on DashboardPack ship with 50+ pages, advanced CRUD interfaces, and dozens of pre-built components — all built to the same standards you see here in SvelteForge Admin.
- Chat — Real-time messaging UI with conversations and contacts
- Kanban — Drag-and-drop project boards
- Calendar — Event management with day/week/month views
- Mail — Full email client interface with folders and compose