Svelte Atoms Core is inspired by chemistry concepts, providing two fundamental building blocks that form the foundation of all UI components: Atoms and Bonds.
The chemistry metaphor reflects how components are structured: atoms are the smallest functional units, while bonds connect and coordinate multiple atoms together.
An Atom is the smallest, reusable UI component with a single responsibility. Each atom represents a fundamental unit of UI functionality and focuses on doing one thing exceptionally well.Key Characteristics:
Single Responsibility: Each atom has one clear purpose
Composable: Atoms can be combined to create complex components
Consistent Base: All atoms inherit from the base atom.svelte component
Headless by Default: No opinionated styling, bring your own CSS
interface LifecycleProps { // Called when component mounts to the DOM onmount?: (node: Element) => void | (() => void); // Called when component is removed from the DOM ondestroy?: (node: Element) => void;}
The as prop enables dynamic element transformation, allowing you to render any HTML element while maintaining the atom’s behavior:
<script> import { HtmlAtom } from '@svelte-atoms/core';</script><!-- Render as a button --><HtmlAtom as="button" class="btn" onclick={() => console.log('clicked')}> Click me</HtmlAtom><!-- Render as a link --><HtmlAtom as="a" href="/home" class="nav-link"> Home</HtmlAtom><!-- Render as a section --><HtmlAtom as="section" class="container"> <HtmlAtom as="h1">Title</HtmlAtom> <HtmlAtom as="p">Paragraph content</HtmlAtom></HtmlAtom>
Use the as prop to ensure semantic HTML while reusing atom behavior and styling patterns.
The base prop enables powerful component composition patterns:
<script> import { HtmlAtom } from '@svelte-atoms/core'; import CustomButton from './CustomButton.svelte';</script><!-- Use another component as base --><HtmlAtom base={CustomButton} class="additional-classes"> Button with custom base</HtmlAtom>
A Bond is a communication mechanism that connects multiple atoms together. Bonds manage shared state and enable coordination between connected atoms and their descendant components.Key Characteristics:
State Management: Maintains internal state accessible to all bonded atoms
Communication: Enables atoms to communicate and coordinate behavior
Scoped Access: Bond state is accessible to bonded atoms and their descendants
Context-Based: Uses Svelte context for state sharing
Bonds are typically created in *-root.svelte components:
<!-- accordion-root.svelte --><script lang="ts"> import { AccordionBond, AccordionState } from './accordion-bond'; let { values = $bindable([]), multiple = false, ...restProps } = $props(); // Create state and bond const state = new AccordionState(() => ({ values, multiple })); const bond = new AccordionBond(state); // Share bond via context bond.share();</script><HtmlAtom {bond} {...restProps}> {@render children?.({ accordion: bond })}</HtmlAtom>
Descendant components can access the bond through context:
<!-- accordion-item.svelte --><script lang="ts"> import { AccordionBond } from './accordion-bond'; // Get the bond from context const accordion = AccordionBond.get(); let { value, ...restProps } = $props(); // Access bond state const isOpen = $derived(accordion.state.props.values.includes(value)); function toggle() { // Modify bond state accordion.toggle(value); }</script><HtmlAtom onclick={toggle} {...restProps}> {#if isOpen} <div class="content">Open content</div> {/if}</HtmlAtom>
Here’s how atoms and bonds work together in the Accordion component:
<script> import { Accordion, AccordionItem } from '@svelte-atoms/core'; let openItems = $state(['item-1']);</script><!-- Bond: Manages which items are open --><Accordion bind:values={openItems} multiple={true} collapsible={true}> <!-- Atoms: Individual accordion items connected via bond --> <AccordionItem.Root value="item-1"> <AccordionItem.Header> First Item <AccordionItem.Indicator /> </AccordionItem.Header> <AccordionItem.Body> Content of first item </AccordionItem.Body> </AccordionItem.Root> <AccordionItem.Root value="item-2"> <AccordionItem.Header> Second Item <AccordionItem.Indicator /> </AccordionItem.Header> <AccordionItem.Body> Content of second item </AccordionItem.Body> </AccordionItem.Root></Accordion>
How the Accordion Bond Works
Root Component: Creates AccordionBond and shares it via context
Item Components: Access the bond to check if they’re open
Header Components: Use bond methods to toggle item state
Indicator Components: React to bond state to show open/closed
State Synchronization: All components stay in sync through the bond
Shared base ensures uniform behavior across all composed components:
<!-- All these components share the same base atom behavior --><Button.Root>Button</Button.Root><Badge.Root>Badge</Badge.Root><Avatar.Root src="/avatar.jpg" /><Input.Root placeholder="Input" />