core Svelte Themes

Core

Headless Svelte 5 UI library for dynamic design systems

@svelte-atoms/core

A modern, headless, and accessible Svelte 5 UI component library built for composability and extensibility.

Why Svelte Atoms?

  • 🎯 Headless First - Complete styling control with sensible defaults
  • 🔗 Bond Architecture - Self-contained state management with context-based communication
  • ♿ Accessible - ARIA attributes, keyboard navigation, and focus management included
  • 🎨 Composable - Build complex UIs by combining simple, reusable components
  • 📘 Type Safe - Full TypeScript support with extensible type definitions
  • âš¡ Svelte 5 Native - Built for Svelte 5 runes, snippets, and modern reactivity

Quick Start

npm install @svelte-atoms/core
<script lang="ts">
    import { Button, Dialog } from '@svelte-atoms/core';

    let open = $state(false);
</script>

<Button onclick={() => (open = true)}>Open Dialog</Button>

<Dialog.Root bind:open>
    <Dialog.Content>
        <Dialog.Header>
            <Dialog.Title>Welcome</Dialog.Title>
        </Dialog.Header>
        <Dialog.Body>
            <p>This is a headless, accessible dialog component.</p>
        </Dialog.Body>
        <Dialog.Footer>
            <Button onclick={() => (open = false)}>Close</Button>
        </Dialog.Footer>
    </Dialog.Content>
</Dialog.Root>

Core Concepts

Composability with base and as

Transform any component into another element or wrap it with custom logic:

<script lang="ts">
    import { Button, Popover, Input } from '@svelte-atoms/core';
</script>

<!-- Button as Popover trigger -->
<Popover.Root>
    <Popover.Trigger base={Button} variant="outline">
        Open Popover
    </Popover.Trigger>
    <Popover.Content>
        <p>Configure your preferences here.</p>
    </Popover.Content>
</Popover.Root>

<!-- Input as Dropdown trigger -->
<Dropdown.Root>
    <Dropdown.Trigger base={Input.Root}>
        <Input.Control placeholder="Search..." />
    </Dropdown.Trigger>
    <Dropdown.Content>
        <!-- items -->
    </Dropdown.Content>
</Dropdown.Root>

Typed Snippets for Extensibility

All components expose typed snippet props for maximum flexibility:

<Dialog.Root>
    {#snippet children({ dialog })}
        <Dialog.Content>
            <Dialog.Body>
                <p>Access the dialog bond directly</p>
                <button onclick={() => dialog.close()}>Close via bond</button>
            </Dialog.Body>
        </Dialog.Content>
    {/snippet}
</Dialog.Root>

Styling with Variants

Create reusable variants locally or globally:

import { defineVariants } from '@svelte-atoms/core/utils';

const buttonVariants = defineVariants({
    class: 'inline-flex items-center justify-center rounded-md',
    variants: {
        variant: {
            primary: 'bg-blue-500 text-white hover:bg-blue-600',
            secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300'
        },
        size: {
            sm: 'h-8 px-3 text-sm',
            md: 'h-10 px-4',
            lg: 'h-12 px-6 text-lg'
        }
    },
    defaults: {
        variant: 'primary',
        size: 'md'
    }
});

Components

Layout: Container, Stack, Layer, Portal
Forms: Input, Textarea, Checkbox, Radio, Select, Combobox, Form
Overlays: Dialog, Drawer, Popover, Tooltip, Toast
Navigation: Tabs, Sidebar, Menu, Dropdown
Display: Card, Alert, Badge, Chip, List, Datagrid, Calendar
Utilities: Root, Lazy, Link, Button

View all components in Storybook →

Documentation

Development

# Clone and install
git clone https://github.com/svelte-atoms/core.git
cd core
bun install

# Start dev server
bun dev

# Build library
bun run build

License

MIT © Svelte Atoms Team

Top categories

Loading Svelte Themes