Installation
Latest version: 5.0.0
Usage
Render the toaster in the root of your app.
import { Toaster, toast } from 'vyrn'
function App() {
return (
)
}Types
Customize the type of toast and pass an options object as the second argument.
toast('Event has been created')Position
Swipe directions are derived from the position automatically.
Layout
Stack layers toasts on top of each other. Normal stacks them vertically.
Rich colors
Semantic surfaces for success, error, info, and warning toasts.
Other
Close button and countdown bar.
Advanced
Inline inputs, grouping, determinate progress, and more.
toast.info('Enter your name', {
duration: 0,
input: {
placeholder: 'Your name',
onSubmit: (value) => toast.success(value),
},
})API Reference
Provider props, toast methods, and options.
Toaster props
Multiple Toasters are safe: only the first one still mounted paints the toasts, so a stray Toaster can never double-render. When it unmounts, the next takes over.
| Name | Type | Default | Description |
|---|---|---|---|
position | 'top-left''top-center''top-right''bottom-left''bottom-center''bottom-right' | 'bottom-right' | Viewport corner where toasts mount. A toast can override this individually. |
layout | 'stack''normal' | 'normal' | stack collapses toasts into a deck that expands on hover; normal lists them vertically. |
visibleToasts | number | 5 | Maximum on screen at once. Extras are queued and shown as space frees up — never discarded. |
duration | number | 4000 | Default auto-dismiss time in ms. Errors default to 5000, loading toasts never auto-dismiss. |
theme | 'light''dark''system' | 'system' | With 'system', your app outranks the OS: a .dark/.light class, a data-theme attribute, or an inline color-scheme is used first, and prefers-color-scheme only if you declare nothing. Theme changes are picked up live. |
dir | 'ltr''rtl''auto' | 'auto' | Text direction. auto reads document.dir. |
richColors | falsetrue'minimal''soft''solid' | false | Semantic surfaces. true maps to 'minimal'; 'soft' adds a border, 'solid' is high contrast. |
expand | boolean | false | Keep a stack layout permanently expanded instead of collapsing it. |
closeButton | boolean | true | Render the close button. Alias: showCloseButton. |
showProgressBar | boolean | true | Show the countdown bar. Driven by one CSS animation, so it costs nothing per frame. |
color | boolean | true | Apply a subtle semantic tint per type. Turn off for uniform neutral surfaces. |
size | 'sm''md''lg' | 'md' | Global density — padding, radius and font size. |
invert | boolean | false | Flip every toast against the page theme. |
gap | number | 14 | Gap between toasts in px. |
offset | stringnumber{ top, right, bottom, left } | '24px' | Distance from the viewport edge. Numbers are px; an object sets each side independently. |
mobileOffset | stringnumber{ top, right, bottom, left } | '16px' | Edge distance below 600px wide. Accepts the same object form. |
swipeDirections | SwipeDirection[] | derived from position | Directions a toast can be swiped away in. Legacy swipeDirection sets a single one. |
swipeThreshold | number | 0.35 | Fraction of the toast's width or height a swipe must cover to dismiss. |
toastOptions | ToastOptions & { types? } | — | Defaults merged into every toast, including classNames. Its types key narrows them per variant, e.g. { types: { error: { duration: 8000 } } }. |
hotkey | string[] | ['altKey', 'KeyT'] | Key combo that moves focus into the toast list. |
pauseWhenPageIsHidden | boolean | false | Pause countdowns while the tab is hidden. Off by default: timers are setTimeout-based, so toasts dismiss on schedule either way. |
pauseOnFocusLoss | boolean | false | Pause countdowns while the window is not focused, so a toast never expires while you are in another app. |
newestFirst | boolean | true | Newest toast sits nearest the viewport edge. Set false to keep the oldest in front and append behind it. |
closeOnClick | boolean | false | Dismiss a toast when its body is clicked. Action and close buttons are excluded. |
loadingIcon | ReactNode | — | Replace the loading spinner. Shorthand for icons.loading. |
containerAriaLabel | string | 'Notifications' | Accessible label for the toast region. |
closeButtonAriaLabel | string | 'Close' | Accessible label for the close button. Translate this for non-English apps. |
icons | { success, info, warning, error, loading, close } | — | Replace any built-in icon with your own node. |
zIndex | number | 9999 | Base stacking order for the toast region. |
className | string | — | Class on the toast list element. Alias: containerClassName. |
toast methods
Every method returns the toast id.
| Name | Type | Default | Description |
|---|---|---|---|
fntoast | (message, options?) | — | Neutral toast. |
fntoast.message | (message, options?) | — | Alias for toast(). |
fntoast.success | (message, options?) | — | Success variant. |
fntoast.error | (message, options?) | — | Error variant. Announced assertively and defaults to a 5000ms duration. |
fntoast.info | (message, options?) | — | Info variant. |
fntoast.warning | (message, options?) | — | Warning variant. Alias: toast.warn. |
fntoast.loading | (message, options?) | — | Spinner that never auto-dismisses until updated or dismissed. |
fntoast.custom | (node(id) => node, options?) | — | No semantic styling. Accepts a render function that receives the toast id, so the node can dismiss itself — the Sonner form. |
fntoast.promise | (promise, options) | — | Drives one toast through loading, success and error. Returns { id, unwrap() } — unwrap re-throws on rejection. Never causes an unhandled rejection. |
fntoast.update | (id, patch) | — | Patch an existing toast. Fields you omit are preserved. |
fntoast.dismiss | (id?) | — | Dismiss one toast, or every toast when called with no argument. |
fntoast.remove | (id) | — | Remove without firing onDismiss. |
fntoast.clearAll | () | — | Legacy alias for toast.dismiss(). |
fntoast.getToasts | () | — | The current queue. |
fntoast.getHistory | () | — | Toasts that have already closed, oldest first. |
fntoast.isActive | (id) | — | Whether a toast is still queued or on screen. |
fnuseVyrn | () => { toasts } | — | Headless hook — render the queue yourself. Alias: useSonner. |
Toast options
Second argument to every toast method.
| Name | Type | Default | Description |
|---|---|---|---|
id | stringnumber | — | Stable id. Passing one that already exists updates that toast instead of adding a duplicate. |
description | ReactNode | — | Secondary line below the message. |
duration | number | 4000 | ms before auto-dismiss. 0 or Infinity keeps it open. |
icon | ReactNode | — | Override the icon for this toast. |
action | { label, onClick, style?, dismiss?, altText? } | — | Single action button. dismiss: false keeps the toast open after the click; altText gives an icon-only button an accessible name. |
actions | ToastAction[] | — | Several action buttons — a Vyrn extension over Sonner's single action. |
cancel | { label, onClick?, className? } | — | Secondary cancel button. |
input | { placeholder, onSubmit, submitLabel?, defaultValue?, allowEmpty? } | — | Inline text field. The countdown pauses while it has focus. |
position | ToastPosition | — | Place this toast in its own corner. |
dismissible | boolean | true | false hides the close button and blocks swipe and Escape. |
important | boolean | false | Announce assertively regardless of type. |
progress | number | — | 0-100 determinate progress. Replaces the duration countdown with a measured bar. |
groupId | string | — | Toasts sharing a group occupy one slot — each new message replaces the last. |
preventDuplicate | boolean | — | Identical text of the same type refreshes the existing toast instead of stacking a second copy. Ideal for retry loops. |
closeOnClick | boolean | — | Per-toast override of the global click-to-dismiss setting. |
priority | 'low''normal''high' | 'normal' | Visual emphasis. high gets an accent ring, low is subdued. |
expandable | boolean | false | Keep actions collapsed until the toast is clicked. Pair with expanded to control it. |
size | 'sm''md''lg' | — | Per-toast density override. |
richColors | boolean'minimal''soft''solid' | — | Per-toast override of the global rich colors setting. |
invert | boolean | — | Invert just this toast. |
className | string | — | Class on the toast element. |
classNames | ToastClassNames | — | Per-part classes: toast, title, description, icon, content, actionButton, cancelButton, closeButton, progressBar, input, plus one per type. |
style | CSSProperties | — | Inline styles. Legacy alias: customStyles. |
unstyled | boolean | false | Strip all built-in styling, keeping only positioning. |
jsx | ReactNode(id) => ReactNode | — | Replace the toast's entire contents. A function receives the toast id. |
customComponent | ComponentType<{ toast, dismiss }> | — | Replace the toast element itself. |
soundEffect | string | — | URL played when the toast appears. |
Callbacks
| Name | Type | Default | Description |
|---|---|---|---|
onClick | (event) => void | — | Makes the whole toast a button, with Enter and Space support. |
onDismiss | (toast) => void | — | Closed by the user or programmatically — not by the timer. |
onAutoClose | (toast) => void | — | Closed because its duration elapsed. |
onClose | () => void | — | Legacy: fires on any close, after onDismiss / onAutoClose. |
Accessibility
Built in — nothing to configure.
| Name | Type | Default | Description |
|---|---|---|---|
Live regions | one politeone assertive | — | Announcements come from a single pair of off-screen regions. Toasts themselves carry no live semantics, so nothing is announced twice and a dismissed toast is never re-read. |
Markup | region > ol > li | — | A labelled region wrapping a semantic ordered list. |
Keyboard | Alt+TEscapeEnter | — | Alt+T moves focus into the list, Escape dismisses, Enter or Space activates a clickable or expandable toast. |
Hover pause | all toasts | — | Hovering or focusing the list pauses every countdown, not just the one under the pointer. |
Motion | prefers-reduced-motion | — | All motion is removed when the OS asks for it. forced-colors is supported too. |
Focus return | automatic | — | Dismissing a focused toast moves focus to the next toast, or back to whatever was focused before you entered the list — never to the document body. |
Hydration | SSR safe | — | The server emits no toast markup, so hydration cannot mismatch even if a toast was dispatched before the Toaster mounted. |