An opinionated toast component for Svelte. Gooey SVG morphing, spring physics, and a minimal API — beautiful by default.
A Svelte port of hiaaryan/sileo.
description for rich toast content.multiple.top-left, top-center, top-right, bottom-left, bottom-center, bottom-right.npm install svelte-sileo
# or
pnpm add svelte-sileo
# or
yarn add svelte-sileo
Add <Toaster /> to your layout. Then call sileo from anywhere.
<script lang="ts">
import { Toaster, sileo } from 'svelte-sileo';
</script>
<Toaster />
<button onclick={() => sileo.success({ title: 'Changes saved' })}>
Toast
</button>
<Toaster /> is single-toast by default. Use <Toaster multiple /> to stack multiple toasts.
sileo.success(opts)sileo.success({ title: 'Changes saved' });
sileo.error(opts)sileo.error({
title: 'Something went wrong',
description: 'Please try again later.'
});
sileo.warning(opts)sileo.warning({ title: 'Storage almost full' });
sileo.info(opts)sileo.info({ title: 'New update available' });
sileo.action(opts)Renders a toast with an inline action button.
sileo.action({
title: 'File uploaded',
description: 'Share it with your team?',
button: {
title: 'Share',
onClick: () => {}
}
});
sileo.promise(promise, opts)Starts in a loading state and transitions to success or error automatically.
sileo.promise(
new Promise((resolve) => setTimeout(resolve, 2000)),
{
loading: { title: 'Saving record...' },
success: { title: 'Record saved' },
error: { title: 'Failed to save' }
}
);
loading accepts only { title, icon }. Use success, error, or action for description, button, and style overrides.
You can also pass a function to success or error to use the resolved value or error:
sileo.promise(fetchUser(), {
loading: { title: 'Loading user...' },
success: (data) => ({ title: `Welcome, ${data.name}!` }),
error: (err) => ({ title: `Error: ${err.message}` })
});
When the promise resolves you can show an action state instead of success:
sileo.promise(uploadFile(), {
loading: { title: 'Uploading...' },
success: { title: 'Done' },
action: { title: 'File ready', button: { title: 'Download', onClick: () => {} } },
error: { title: 'Upload failed' }
});
sileo.show(opts)Generic toast with no default state icon.
sileo.show({ title: 'Hello world' });
sileo.dismiss(id)Dismiss a specific toast by id.
const id = sileo.success({ title: 'Saved' });
sileo.dismiss(id);
sileo.clear(position?)Remove all toasts immediately, optionally scoped to a position.
sileo.clear();
sileo.clear('top-right');
Every method accepts a SileoOptions object:
| Option | Type | Description |
|---|---|---|
id |
string |
Optional stable id for in-place updates/replacement. In single mode, omitting it uses a shared id (sileo-default). In multiple mode, omitting it generates a unique id. |
title |
string |
Main toast text. |
description |
string | Component |
Expandable body. Accepts plain text or a Svelte component. |
button |
{ title: string, onClick: () => void } |
Inline action button. |
icon |
Component | null |
Replaces the default state icon. Pass null to hide the icon. |
duration |
number | null |
Auto-dismiss delay in ms. null = persistent. Default 6000. |
position |
SileoPosition |
Overrides the <Toaster> position for this toast. |
fill |
string |
Background fill color of the pill. Default #FFFFFF. |
roundness |
number |
Border radius of the pill. Default 16. |
autopilot |
boolean | { expand?: number, collapse?: number } |
Auto-expand/collapse timing. |
styles |
SileoStyles |
Per-element class overrides (title, description, badge, button). |
| Prop | Type | Default | Description |
|---|---|---|---|
position |
SileoPosition |
top-right |
Where toasts appear. |
offset |
number | string | object |
— | Edge offset. Accepts a value or { top, right, bottom, left }. |
multiple |
boolean |
false |
false: single-toast mode (replace current). true: stack multiple toasts. |
options |
Partial<SileoOptions> |
— | Default options applied to every toast. |
Single mode is the default:
<Toaster />
Multiple mode:
<Toaster multiple />
Pass any Svelte component as description for rich content:
<!-- InvoiceToast.svelte -->
<div class="flex flex-col gap-2">
<span class="text-xs opacity-50">Invoice #INV-2024-001</span>
<span class="font-medium">$1,200.00 · 3 items</span>
</div>
import InvoiceToast from './InvoiceToast.svelte';
sileo.success({
title: 'Invoice sent',
description: InvoiceToast,
button: { title: 'View', onClick: () => {} }
});
import RocketIcon from './RocketIcon.svelte';
sileo.success({
title: 'Deployed',
icon: RocketIcon
});
Sometimes you need to update global settings imperatively.
sileo.setPosition(position)Updates the toaster position dynamically.
import { sileo } from 'svelte-sileo';
sileo.setPosition('bottom-center');
sileo.setOptions(options)Updates the default options dynamically.
import { sileo } from 'svelte-sileo';
sileo.setOptions({ duration: 3000 });
sileo.setMultiple(enabled)Toggles single/multiple mode programmatically.
import { sileo } from 'svelte-sileo';
sileo.setMultiple(true);
Sileo is designed to look great out of the box. When you need to customize, there are a few escape hatches.
The fill prop sets the SVG background color of the toast. The default is #FFFFFF. Set it to a dark color like #171717 or black to create a dark toast — just make sure to pair it with light text via styles.
sileo.success({
title: 'Dark Mode',
fill: '#171717',
styles: {
title: 'text-white'
}
});
The styles prop lets you override classes on individual sub-elements. Use Tailwind's ! modifier to ensure specificity if needed.
| Key | Element | Selector |
|---|---|---|
title |
The heading text | [data-sileo-title] |
description |
The body/description area | [data-sileo-description] |
badge |
The icon badge circle | [data-sileo-badge] |
button |
The action button | [data-sileo-button] |
sileo.success({
title: 'Custom styled',
styles: {
title: 'text-lg font-bold',
description: 'italic'
}
});
Control the border radius with the roundness prop (default 16). Set it lower for sharper corners or higher for a rounder pill shape.
Note: Higher
roundnessvalues increase the SVG blur radius used for the gooey morph effect, which is more expensive to render. The recommended value is16for a good balance between aesthetics and performance.
By default, toasts auto-expand after a short delay and collapse before dismissing. Control this with the autopilot prop.
autopilot: false — disables auto expand/collapse entirely (hover to expand).autopilot: { expand: ms, collapse: ms } — custom timing for each phase. Use the Toaster's options prop to set defaults for every toast. This is useful for applying a consistent dark theme across your app.
<Toaster
position="top-right"
options={{
fill: "#171717",
roundness: 16,
styles: {
title: "text-white!",
description: "text-white/75!",
badge: "bg-white/10!",
button: "bg-white/10! hover:bg-white/15!",
},
}}
/>
Sileo exposes CSS custom properties you can override globally to change state colors, dimensions, or animation timing.
:root {
/* State colors (oklch) */
--sileo-state-success: oklch(0.723 0.219 142.136);
--sileo-state-loading: oklch(0.556 0 0);
--sileo-state-error: oklch(0.637 0.237 25.331);
--sileo-state-warning: oklch(0.795 0.184 86.047);
--sileo-state-info: oklch(0.685 0.169 237.323);
--sileo-state-action: oklch(0.623 0.214 259.815);
/* Dimensions */
--sileo-width: 350px;
--sileo-height: 40px;
/* Animation */
--sileo-duration: 600ms;
}
<!-- Available: top-left · top-center · top-right · bottom-left · bottom-center · bottom-right -->
<Toaster position="bottom-center" />