svelora
v3.2.8
Published
Modern primitive-based UI component library for Svelte 5
Maintainers
Readme
Install
bun add svelora mode-watcher
# npm install svelora mode-watcher
# pnpm add svelora mode-watcher
# yarn add svelora mode-watcher<script lang="ts">
import 'svelora/theme.css'
import { ModeWatcher } from 'mode-watcher'
</script>
<ModeWatcher />/* layout.css */
@import 'svelora/theme.css';<script lang="ts">
import { Avatar, Button, ThemeModeButton, toast } from 'svelora'
import { ModeWatcher } from 'mode-watcher'
</script>
<ModeWatcher />
<Button variant="soft" color="primary" leadingIcon="lucide:edit">Edit</Button>
<ThemeModeButton />
<Avatar src="/photo.jpg" alt="Jane" size="lg" />Features
- Svelte 5 — Runes, snippets, latest reactivity
- Tailwind CSS 4 — Utility-first with Tailwind Variants
- Fully Typed — Strict TypeScript, exported prop types
- Accessible — Built on Bits UI & Vaul Svelte
- 200,000+ Icons — Iconify integration
- Themeable — OKLCH color tokens, light/dark mode, global config
- Hooks — 16 reactive hooks for common UI patterns
Hooks
Reactive hooks built on Svelte 5 runes and actions.
<script>
import { useMediaQuery, useClipboard, useEventListener } from 'svelora'
const isMobile = useMediaQuery('(max-width: 640px)')
const clipboard = useClipboard()
let width = $state(0)
useEventListener(() => window, 'resize', () => {
width = window.innerWidth
})
</script>
{#if isMobile.matches}
<MobileLayout />
{/if}
<Button onclick={() => clipboard.copy('Hello!')}>
{clipboard.copied ? 'Copied!' : 'Copy'}
</Button>
<p>{width}px</p>| Hook | Type | Description |
| ------------------- | -------------- | ---------------------------------------------- |
| useMediaQuery | Runes | Reactive CSS media query tracking |
| useClipboard | Runes | Copy text with auto-reset state |
| useFormField | Context | Access FormField context from child components |
| useClickOutside | Action | Detect clicks outside an element |
| useInfiniteScroll | Runes + Action | Auto-load on scroll with loading state |
| useEscapeKeydown | Action | Listen for Escape key |
| useDebounce | Runes | Debounce with pending, cancel, flush |
| useDebouncedState | Runes | Bindable debounced state helper |
| useEventListener | Runes | Reactive event listeners with cleanup |
| useResizeObserver | Runes | Observe element size changes |
| useElementSize | Runes | Read reactive element width and height |
| useIntersectionObserver | Runes | Track viewport intersection state |
| useScrollLock | Runes | Lock and restore document scrolling |
| useFocusTrap | Runes | Keep focus inside a container |
| useLocalStorage | Runes | SSR-safe localStorage binding |
| useThrottle | Runes | Throttle reactive updates |
| useTimeout | Runes | Schedule cancellable one-shot timers |
| useInterval | Runes | Schedule cancellable repeating timers |
Customization
<!-- Per-instance -->
<Button ui={{ base: 'rounded-full shadow-lg' }}>Custom</Button>// Global defaults
import { defineConfig } from 'svelora'
defineConfig({
button: { defaultVariants: { variant: 'outline' } },
icons: { loading: 'lucide:loader' }
})/* Custom colors */
:root {
--color-primary: oklch(0.55 0.25 270);
}Publish
Release checklist: RELEASE_CHECKLIST.md
bun run release:verifyOne command publish:
bun run publicThe publish command generates CHANGELOG.md automatically from unreleased git commits.
It groups commit messages into Added, Changed, and Fixed, writes the next version section, resets ## [Unreleased] back to the template automatically, commits local changes if needed, publishes to npm, tags the release, and pushes everything.
Refresh the template manually if needed:
bun run changelog:templateOther version bumps:
bun run public:minor
# bun run public:majorFull verification before publish:
bun run public:fullDry run:
bun run public:drybun run public:minor:dry
# bun run public:major:drynpm login
npm publish --access publicIf you want to include the full test suite before publishing:
bun run release:verify:full