React toast · Vue · Svelte · vanilla · zero deps
alert-notify
Tiny toast notifications for React and everything else.~4.7KB gzipped JS — a lightweight alternative to react-toastify, react-hot-toast, Sonner, and react-alert. No root provider required.
Live demo
Fire toasts from the browser. Same API every framework gets.
Complete API reference
Nothing is required beyond importing the package and CSS. The portal auto-mounts. Below is every method, option, and default.
Required setup
import { toast } from "alert-notify";
import "alert-notify/style.css";
// That's it. No provider. No root container.
toast.success("Hello");Methods
| Method | Returns | Description |
|---|---|---|
toast(title, options?) | ToastId | Generic toast (message type) |
toast.success(title, options?) | ToastId | Success toast |
toast.error(title, options?) | ToastId | Error toast |
toast.warning(title, options?) | ToastId | Warning toast |
toast.info(title, options?) | ToastId | Info toast |
toast.loading(title, options?) | ToastId | Loading toast (sticky by default) |
toast.message(title, options?) | ToastId | Neutral message toast |
toast.promise(promise, messages) | Promise<T> | Loading → success/error on same id |
toast.dismiss(id?) | void | Dismiss one toast, or all if omitted |
toast.config(partial) | void | Update global toaster defaults |
toast.getConfig() | ToasterConfig | Read current global config |
toast.getToasts() | ToastRecord[] | Current toast list (headless) |
toast.subscribe(listener) | () => void | Subscribe to toast list changes |
toast.destroy() | void | Dismiss all + remove portal |
createToaster(config?, options?) | ToasterInstance | Isolated toaster (multi-instance) |
Per-toast options
Passed as the second argument to any toast.* method.
| Option | Type | Default | Description |
|---|---|---|---|
id | string | auto UUID | Stable id. Same id updates in place (coalesce) |
type | ToastType | from method | success | error | warning | info | loading | message |
description | string | — | Secondary text under the title |
duration | number | config / Infinity for loading | Ms until auto-close. Use Infinity for sticky |
icon | string | HTMLElement | false | built-in SVG | Custom icon HTML/node, or false to hide |
html | string | — | Opt-in unescaped title HTML (prefer plain text) |
action | { label, onClick } | — | Primary action button (e.g. Undo) |
cancel | { label, onClick } | — | Secondary cancel button |
closeButton | boolean | from config (true) | Show × button |
dismissible | boolean | from config (true) | Allow swipe / close dismiss |
important | boolean | false | Jump to front of the queue |
className | string | — | Extra class on the toast element |
style | object | — | Inline styles on the toast |
onDismiss | (toast) => void | — | Manual dismiss (close / swipe / dismiss) |
onAutoClose | (toast) => void | — | Fired when duration timer ends |
Global config (toast.config)
Sets defaults for all toasts. Optional wrappers pass the same props.
| Key | Type | Default | Description |
|---|---|---|---|
position | ToastPosition | "top-right" | 6 corners + top/bottom center |
theme | "light" | "dark" | "system" | "system" | Color scheme. System also tracks html.dark / data-theme |
duration | number | 4000 | Default auto-close ms |
closeButton | boolean | true | Show close button by default |
dismissible | boolean | true | Allow dismiss by default |
richColors | boolean | false | Tinted success/error/warning/info surfaces |
visibleToasts | number | 3 | Max visible in the stack |
expand | boolean | false | Always expand stack (else expand on hover) |
gap | number | 12 | Gap between expanded toasts (px) |
offset | number | string | 16 | Distance from viewport edge |
dir | "ltr" | "rtl" | "auto" | "auto" | Text direction |
pauseOnHover | boolean | true | Pause timers while hovering the stack |
pauseOnWindowBlur | boolean | true | Pause timers when the window loses focus |
progressBar | boolean | true | Show duration progress bar |
toasterClassName | string | — | Class on the toaster container |
style | object | — | Inline styles on the toaster container |
Promise API
toast.promise(uploadFile(), {
loading: "Uploading…",
success: (file) => `Uploaded ${file.name}`,
error: (err) => (err instanceof Error ? err.message : "Failed"),
});
// Or pass full option objects:
toast.promise(save(), {
loading: { title: "Saving…", description: "Please wait" },
success: { title: "Saved", duration: 3000 },
error: { title: "Failed", important: true },
});Multiple toasters & headless
import { createToaster } from "alert-notify";
// Isolated instance (own portal + config)
const modalToast = createToaster({ position: "bottom-center" });
modalToast.success("Saved in modal");
// Headless — you render the UI
const headless = createToaster({}, { headless: true });
headless.subscribe((toasts) => {
// render custom UI from toasts[]
});Optional framework wrappers
Not required. They only sync config from props. Accept the same keys as toast.config.
| Import | Usage |
|---|---|
alert-notify/react | <Toaster position="top-right" richColors /> |
alert-notify/vue | <Toaster position="top-right" :rich-colors="true" /> |
alert-notify/svelte | <Toaster position="top-right" richColors /> |
Behavior notes
- Title/description are HTML-escaped by default. Use
htmlonly when you intend markup. loadingtoasts default toduration: Infinityuntil updated (e.g. via promise).- Same
idcoalesces — updates the existing toast instead of stacking a duplicate. - Escape dismisses the focused toast. Swipe/drag dismisses when
dismissibleis true. - SSR-safe: no DOM work until
documentexists. - CSS import is recommended but optional if you ship your own styles using the same class names / variables.
Built for the smallest useful toast
Looking for a React toast, snackbar, or notification library that does not crush your bundle? Core JS is about 4.7KB gzip(16,006 bytes minified). CSS is optional and ~2.3KB gzip. No runtime dependencies. Tree-shake friendly ESM + CJS + CDN builds.
Compared with common React toast / toastify libraries (approx. gzip JS):
- alert-notify ~4.7KB — React, Vue, Svelte, Angular, vanilla
- react-hot-toast ~4–5KB — React only
- Sonner ~10–12KB — React only
- react-toastify (toastify) ~40KB+ — React only
React toast, notifications, alerts & snackbars
One API for the jobs people usually split across react toast, react notification, react-alert, and snackbar packages. Works the same in Vue, Svelte, Angular, Astro, and CDN HTML.
- React toast notifications —
toast.success,toast.error, promise toasts, Undo actions. - React alerts — drop-in feel for react-alert style success / error / info messages.
- Snackbars — positioned stacks, dismiss, pause on hover, progress bar.
- Toastify-style flows — typed helpers plus
toast.promisewithout the toastify bundle weight. - Cross-framework apps — same package in a React app, Vue island, or plain script tag.
How to use
Import styles once. Call toast.* from anywhere. Optional <Toaster /> wrappers only sync config props — the portal auto-mounts.
import { toast } from "alert-notify";
import "alert-notify/style.css";
toast.success("Saved");
toast.error("Failed", { description: "Try again" });
// No container. Portal mounts itself.// App.tsx
import { toast } from "alert-notify";
import { Toaster } from "alert-notify/react";
import "alert-notify/style.css";
export function App() {
return (
<>
<Toaster position="top-right" richColors />
<button onClick={() => toast.success("Saved")}>Save</button>
</>
);
}<!-- App.vue -->
<script setup>
import { toast } from "alert-notify";
import { Toaster } from "alert-notify/vue";
import "alert-notify/style.css";
</script>
<template>
<Toaster position="top-right" rich-colors />
<button @click="toast.success('Saved')">Save</button>
</template><!-- +layout.svelte / App.svelte -->
<script>
import { toast } from "alert-notify";
import Toaster from "alert-notify/svelte";
import "alert-notify/style.css";
</script>
<Toaster position="top-right" richColors />
<button on:click={() => toast.success("Saved")}>Save</button>// any.component.ts
import { toast } from "alert-notify";
import "alert-notify/style.css";
show() {
toast.success("Saved");
}
// Optional: call toast.config({...}) once in AppComponent.ngOnInit
// No Angular module or container component required.---
// client script or framework island
---
<script>
import { toast } from "alert-notify";
import "alert-notify/style.css";
document.querySelector("button")?.addEventListener("click", () => {
toast.success("Saved");
});
</script><link rel="stylesheet" href="https://unpkg.com/alert-notify@2/dist/style.css" />
<script src="https://unpkg.com/alert-notify@2/dist/alert-notify.global.js"></script>
<script>
AlertNotify.toast.success("Hello from CDN");
</script>Dark mode & CSS variables
Set theme to light, dark, or system. System mode follows the OS, plus html.dark / data-theme="dark". Rebrand colors by overriding CSS variables in your own stylesheet.
// Dark mode
toast.config({ theme: "system" }); // OS + html.dark / data-theme
toast.config({ theme: "dark" });
toast.config({ theme: "light" });
toast.config({ richColors: true }); // soft tinted fills/* your-app.css — after alert-notify/style.css */
.an-toaster {
--an-bg: #ffffff;
--an-fg: #0f172a;
--an-muted: #64748b;
--an-border: rgba(15, 23, 42, 0.1);
--an-success: #16a34a;
--an-error: #e11d48;
--an-warning: #ca8a04;
--an-info: #2563eb;
/* Soft rich fills */
--an-success-bg: #ecfdf5;
--an-success-border: #a7f3d0;
--an-error-bg: #fff1f2;
--an-error-border: #fecdd3;
--an-warning-bg: #fffbeb;
--an-warning-border: #fde68a;
--an-info-bg: #eff6ff;
--an-info-border: #bfdbfe;
}
.an-toaster[data-theme="dark"] {
--an-bg: #1e293b;
--an-fg: #f8fafc;
--an-success: #4ade80;
--an-error: #fb7185;
--an-warning: #facc15;
--an-info: #60a5fa;
--an-success-bg: #14532d;
--an-error-bg: #4c0519;
--an-warning-bg: #422006;
--an-info-bg: #1e3a8a;
}Exports
import {
toast,
createToaster,
} from "alert-notify";
import { Toaster } from "alert-notify/react"; // optional
import { Toaster } from "alert-notify/vue"; // optional
import Toaster from "alert-notify/svelte"; // optional
import "alert-notify/style.css";Alternative to toastify, Sonner, hot-toast & react-alert
If you landed here searching for react toast, toastify, tostify, react-toastify, react-hot-toast, Sonner, react-alert, notistack, or a React notification / snackbar library — alert-notify is built for that search, with a smaller footprint and no React-only lock-in.
| You might know | Why people switch |
|---|---|
| react-toastify / toastify | Popular React toastify stack; larger bundle. alert-notify targets the same toast UX in ~4–5KB with no framework lock-in. |
| react-hot-toast | Minimal React toasts. alert-notify matches the imperative feel and stays usable outside React. |
| Sonner | Polished React toasts. alert-notify is smaller and framework-agnostic if you ship Vue, Svelte, or vanilla too. |
| react-alert / react notifications | Alert and notification patterns for React. Use toast.success / toast.error / toast.info for the same messaging jobs. |
| notistack / snackbars | Material-style snackbars. alert-notify covers snackbar-like toasts with positions, actions, and stacking. |
FAQ
Common questions about React toasts, toastify alternatives, and framework-agnostic notifications.
What is a good React toast notification library?
alert-notify is a tiny (~4.7KB gzip) toast notification library for React and every other framework. Call toast.success / toast.error from anywhere — no root provider. It is a lightweight alternative to react-toastify, react-hot-toast, Sonner, react-alert, and notistack.
Is alert-notify an alternative to react-toastify or toastify?
Yes. If you searched for react-toastify, toastify, or tostify, alert-notify covers the same job — success, error, warning, info, loading, and promise toasts — in a much smaller package with zero runtime dependencies and no React lock-in.
Can I use it instead of react-hot-toast or Sonner?
Yes. alert-notify is similar in spirit to react-hot-toast and Sonner (simple imperative API, stacking, rich colors) but works in React, Vue, Svelte, Angular, Astro, and plain HTML. Optional <Toaster /> wrappers exist for React, Vue, and Svelte.
Does it replace react-alert or other React notification / snackbar libs?
If you need react-alert style notifications, React snackbars, or general React notification toasts, alert-notify can replace them. Same patterns: success/error messages, actions like Undo, dismiss, and position control — without a required container.
Does it work without React?
Yes. The core is vanilla TypeScript. Use it from Vue, Svelte, Angular, Astro islands, or a CDN script tag. Framework packages only sync config props; the portal auto-mounts.
How do I install and show a toast?
npm install alert-notify, import alert-notify/style.css, then call toast.success("Saved") or toast.error("Failed"). No provider and no root portal component are required.