Quick Start
Get up and running with Svelte Atoms in minutes. This guide will walk you through installation, configuration, and your first component.
Requirements
Make sure your project meets the following requirements:
-
Svelte 5
Svelte Atoms is built for Svelte 5 and uses the new Runes API.
-
Tailwind CSS (Version 4)
Components are styled with Tailwind CSS utilities for easy customization.
-
Node.js 18+
Modern Node.js version for build tools and development.
Installation
Install @svelte-atoms/core using your preferred package manager:
npm install @svelte-atoms/core Configuration
After installing the package, you need to configure your project to use the Svelte Atoms components and styling system.
Import Internal Styles
Import the internal style file in your root layout file (e.g., src/routes/+layout.svelte) to load the base styles for all components:
src/routes/+layout.svelte Svelte<script>
import '@svelte-atoms/core/styles/tw';
import './app.css'; // Override @svelte-atoms/core styles here
let { children } = $props;
</script>
{@render children?.()}Important
Make sure to import the internal styles before your app.css to ensure proper style precedence.
Setup App CSS for Tailwind
Create or update your app.css file to include Tailwind directives and CSS variables that Svelte Atoms uses:
src/app.css CSS@import 'tailwindcss';
@source './../node_modules/@svelte-atoms/core/**/*.{js,ts,svelte}'
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--radius: 0.625rem;
--shadow-x: 0px;
--shadow-y: 1px;
--shadow-blur: 2px;
--shadow-spread: 0px;
--shadow-opacity: 0.18;
--shadow-color: hsl(0 0% 0%);
--tracking-normal: 0em;
--spacing: 0.25rem;
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--destructive-foreground: oklch(0.985 0 0);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--shadow-color: hsl(0, 0%, 100%);
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--radius-inherit: inherit;
}
These CSS variables provide a complete theming system with light and dark mode support. You can customize these values to match your brand colors.
Note
Make sure to include node_modules/@svelte-atoms/core/**/* in your content array so Tailwind can detect classes used in the library components.
Configure Component Preset
Create a preset file to customize the default styles for Svelte Atoms components. This allows you to define your own variants and default classes:
src/preset.ts TypeScriptimport { type Preset } from '@svelte-atoms/core';
export const preset: Partial<Preset> = {
button: () => ({
class: 'flex items-center px-3 py-2 h-12 transition-colors',
variants: {
variant: {
primary: {
class: 'bg-primary text-primary-foreground hover:bg-primary/80'
},
outline: {
class: 'border border-border hover:bg-accent'
}
}
},
defaults: {
variant: 'primary'
}
}),
badge: () => ({
class: 'inline-flex items-center rounded-md px-2 py-1 text-xs',
variants: {
variant: {
primary: {
class: 'bg-primary text-primary-foreground'
},
secondary: {
class: 'bg-secondary text-secondary-foreground'
}
}
}
})
};Your First Component
Now that everything is configured, let's create a simple example using a Button component:
src/routes/+page.svelte Svelte<script lang="ts">
import { Button } from '@svelte-atoms/core';
let count = $state(0);
</script>
<div class="flex items-center gap-4 p-8">
<Button onclick={() => count++}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</Button>
<Button variant="outline" onclick={() => count = 0}>
Reset
</Button>
</div>Success!
You now have a working setup with Svelte Atoms. The components are fully styled and ready to use.
Next Steps
Now that you have Svelte Atoms set up, here are some recommended next steps:
Browse Components
Explore the full library of accessible, composable components.
View all componentsLearn the Philosophy
Understand the Bond architecture and design principles behind Svelte Atoms.
Read the philosophyStyling Guide
Learn how to customize component styles and create your own design system.
Styling guideAccessibility
Discover how Svelte Atoms ensures your applications are accessible to everyone.
Accessibility guideNeed Help?
If you're still having issues, check out our GitHub repository for more examples and to report bugs.
View on GitHub