Toast
Promise-aware toasts with stacking, swipe to dismiss and correct live regions.
npm install @devix-labs/toast
Toast notifications with promise toasts, actions and undo, swipe to dismiss, a stack that fans out on hover and a queue so a burst never floods the page. Timers pause on hover, on focus and while the tab is hidden. The region renders in the browser's top layer and moves inside an open modal dialog, because a modal makes everything outside it inert — which is why toasts over modals are dead everywhere else. No dependencies, no framework, nothing injected into your CSP.
What you get
Works over a modal
A modal dialog makes everything outside it inert. The toaster moves inside the open modal, so Undo is still a button you can press.
Pauses when you are looking
On hover, while focus is inside the toast, and while the tab is in the background — a message is never spent on an empty screen.
Promise toasts
One toast turns from loading into success or error in place, and your promise is handed straight back to your own code.
A queue, not a flood
Three on screen by default, the rest waiting behind. The stack keeps one footprint and fans out when you hover it.
4 KB, no dependencies
toastr needs 29.6 KB of jQuery and stopped in 2023; react-hot-toast and sonner need React. This needs nothing.
Nothing injected
No <style> tag, no eval: a strict Content Security Policy needs no nonce. Theming is CSS variables and your own classes.
Toast — overview
Why it exists
The most-downloaded vanilla toaster (toastr) has been unmaintained since 2023 and still needs jQuery. The React ones are good and framework-bound. And all of them share the same four open complaints: no dismiss button, toasts stuck under modals, a CSP that needs a nonce because styles are injected, and no way to stop a burst from covering the page.
What it does differently
- 4.1 kB gzip, no dependencies, no framework. The same call in React, Vue, Svelte or a script tag.
- Usable over a modal. A modal
<dialog>makes everything outside it inert; the toaster moves inside the open modal so "Undo" is still a button you can press. - Pauses when you are looking. Hover, focus, hidden tab.
- A queue, not a flood.
maxon screen, the rest wait. - Promise toasts that resolve in place and still hand your promise back.
- Nothing injected. The CSS is a file; strict CSP pages need no nonce.
Shape of the package
| Entry | What |
|---|---|
@devix/toast |
toast, configure, createToaster |
@devix/toast/react, /vue, /svelte, /element |
the same toaster, wrapped |
@devix/toast/jquery |
a toastr.* adapter for pages that still call it |
@devix/toast/styles.css, /styles.layer.css |
the theme, plain or inside @layer devix |
Not in 1.0
A persistent notification centre (history, read state, broadcasting from Laravel) is the Pro edition's shape, not a gap in the free core.
Demos
All demos →The basics
Every type, a description, an action to undo — and a countdown that pauses the moment you hover.
Promise toasts
One toast that follows the work: loading, then success or error, in place — and your promise still resolves.
The stack
Newest in front, older ones tucked behind, the rest queued — and the whole stack fans out when you hover it.
Over a modal
A modal makes everything outside it inert, so a toast on top of one is usually dead. This one still works.
Theming
Rich colours, a compact size, your own icons — variables and classNames, no stylesheet fork.
How it compares
Questions
Do I have to mount anything?
No. The first toast builds its own region, so `import { toast } from '@devix/toast'` and a call are the whole setup. React and Vue have a <Toaster /> that carries settings and renders nothing.
Why are my toasts not clickable over a modal elsewhere?
Because a modal <dialog> makes everything outside it inert — visible, but dead to the pointer. This toaster detects an open modal and moves the region inside it, then moves it back when the modal closes.
Can I call it outside a component?
Yes. The toaster is a module-level object, not a context, so an axios interceptor, a store or a web worker's message handler can all call toast().
What happens when fifty toasts arrive at once?
Three are shown (configurable) and the rest queue, oldest first. The stack collapses into one footprint and fans out when you hover it.
Does it work with a strict CSP?
Yes — no <style> element is ever injected and there is no eval, so no nonce is needed. This is react-hot-toast's issue #138, still open.
Can I style it like the rest of my app?
Every visual decision is a CSS variable, every part takes your own classes per toaster or per toast, icons and words are replaceable, and render() lets you draw the whole toast while keeping the timing, stacking and swipe.
More from Devix
All resources →Confirm Dialog
UI component
Promise-based dialogs on native <dialog>: confirm, prompt and type-to-confirm.
Command Palette
UI component
A framework-free ⌘K palette with nested pages, async sources and shortcuts.
Cookie Consent
Plugin
Blocks scripts until consent, supports Consent Mode v2, GDPR and UAE PDPL.