
Toasts you can put anywhere.
Zero-dependency React notifications.
toast.success("Project saved", <FiCheck />, { bgColor: "#052e16", width: 360 });npm i ztoast<Toaster />toast.success("Hello World")Examples
Positioning
A position can be a named spot, a distance from the edges, or a coordinate. Toasts that resolve to the same spot share a stack; different spots stack independently. Nothing is clamped to the viewport, so a coordinate can hang a toast off the edge on purpose.
Playground
Every control below is a real option. Only what you change from the defaults ends up in the generated call, so you can copy it straight into your code.
The icon argument is "💾", which replaces the built-in variant icon. Drop the second argument completely and you get the variant icon back.
API reference
Every method, every config option and every default. Numbers mean pixels everywhere, and colours accept hex, rgb(), hsl(), oklch(), rgb(0 0 0 / 50%) and css variables.
toast.show(message, icon?, config?)coreThe neutral variant, with no built-in icon. Every creator has this same signature: only the message is required, and the second argument can be either the icon or the config.
toast.success(message, icon?, config?)variantA success toast with the green check icon, replaced by anything you pass as the icon argument.
toast.error(message, icon?, config?)variantRendered as role="alert" with aria-live="assertive", so screen readers announce it immediately.
toast.info(message, icon?, config?)variantAn informational toast.
toast.warning(message, icon?, config?)variantA warning toast.
toast.warn(message, icon?, config?)aliasAn alias of toast.warning. Identical behaviour, shorter to type.
toast.loading(message, icon?, config?)variantDefaults to duration: Infinity, so it stays until you dismiss it or replace it by reusing its id. Pass a duration to override that.
toast.promise(promise, messages, config?)asyncTracks a promise through loading, resolved and rejected in a single toast. It returns the original promise, so you can still await it. success and error accept a node or a function of the resolved value / error.
toast.dismiss(id?)controlPlays the exit animation, then removes the toast. Called with no argument it dismisses every toast.
toast.dismissAll()controlThe same as calling toast.dismiss() with no argument.
useToast()hookOptional hook for components that want to read the live toast list. It returns the imperative api alongside it, works anywhere in the tree, and never throws — there is no provider to be inside of.
Upgrading from 0.1.7
0.1.8 replaced the provider and the raw css option names, and later releases keep that same api. Most apps are a two-line change: swap the provider for <Toaster />, then rename the handful of options below.
| 0.1.7 | 0.1.8 and later |
|---|---|
| <ToastProvider>…<ToastViewport /></ToastProvider> | <Toaster /> |
| defaultPosition / defaultDuration / defaultProgressBar | position / duration / progress |
| toast.show(msg, { icon: <I /> }) | toast.show(msg, <I />) — the object form still works |
| background / borderRadius / boxShadow / progressBar | bgColor / radius / shadow / progress |
| backgroundGradient / backgroundImage | bgColor — it takes gradients and urls |
| { position: "top-center", top: "50vh" } | { position: "top-50vh" } |
| { offset: { bottom: 40, right: 32 } } | { position: "bottom-40px right-32px" } |
| progressBar was off by default | progress is on by default |
| useToast() threw outside a provider | useToast() works anywhere and never throws |
| toasts fired before mount were dropped | they are queued and appear when the Toaster mounts |
Gone for good
These exports and options no longer exist. If your editor still autocompletes them, delete your build cache and reinstall.
ToastProviderToastViewportToastContextValueToastProviderPropsToastOptionsToastStyleOptionsToastOffsetOptionsPromiseToastMessagesoffsettop / bottom / left / righttransformborderColorborderWidth