Atlas survey

React toast libraries in 2026: Sonner, react-toastify, react-hot-toast, notistack and the design-system natives

Sonner is the 2026 default (41M weekly installs, shadcn's toast); react-toastify is the actively-released power option; react-hot-toast is the 4.7 kB minimalist; notistack is legacy.

41 sources ~10 min read #3 react · toast · notifications · sonner · react-toastify · react-hot-toast · notistack · shadcn · bundle-size

Decision. Reach for Sonner ⭐ 12.6k unless you have a reason not to — it is what shadcn add sonner installs, it has zero runtime dependencies, and at 41.4M weekly npm installs it is now an order of magnitude more installed than anything else in this category [1] [2]. Reach for react-toastify ⭐ 13.4k when you need a deep, configurable feature surface (custom progress bars, notification centre, CSP nonce) and the most recent release cadence — v11.1.0 shipped April 2026 [3]. Reach for react-hot-toast ⭐ 11k when bundle size dominates (4.7 kB gz, roughly half of everything else) [4]. If you already ship Mantine, Chakra v3 or Base UI, use the in-house toaster — it costs ~0 marginal bytes. notistack ⭐ 4.1k is the one to avoid for greenfield: no npm release since January 2025 [5].

All numbers below were fetched live on 2026-07-13 (npm registry, npm downloads API, Bundlephobia, GitHub). Star counts and sizes shift; the ledger records what was measured.

At a glance

Library ⭐ Stars Weekly installs min+gzip Runtime deps Latest release Open issues React 19
Sonner [6] ⭐ 12.6k 41.4M [1] 9.2 kB (33.4 kB min) [7] 0 [1] 2.0.7 — 2025-08-02 [1] 52 [8] ✓ peer ^18 \|\| ^19 [1]
react-toastify [9] ⭐ 13.4k 4.0M [10] 9.5 kB (33.6 kB min) [11] 1 (clsx) [10] 11.1.0 — 2026-04-19 [3] 72 [12] ✓ explicit v11 fix [13]
react-hot-toast [14] ⭐ 11k 3.4M [15] 4.7 kB (11.9 kB min) [4] 2 (goober, csstype) [15] 2.6.0 — 2025-08-15 [16] ⚠ 115 [17] ✓ types fixed in 2.5.2 [16]
notistack [18] ⭐ 4.1k 1.4M [5] 8.2 kB (23.4 kB min) [19] 2 (clsx, goober) [5] ⚠ 3.0.2 — 2025-01-18 [5] 53 [20] ✓ peer allows ^19 [5]
@mantine/notifications [21] ⭐ 31k (Mantine) 741k [41] 5.5 kB (+ @mantine/core) [22] peer: @mantine/core 9.4.1 — 2026-06-28 [22]
Chakra UI v3 Toaster [23] ⭐ 41k (Chakra) part of @chakra-ui/react 3.36.0 (293 kB gz whole lib, tree-shaken) [24] Ark UI 3.36.0 — 2026-06-10 [24]
MUI Snackbar [25] ⭐ 99k (MUI) part of @mui/material 9.2.0 (146.6 kB gz whole lib) [26] 9.2.0 — 2026-07-03 [26]
Base UI Toast [27] ⭐ 10k (Base UI) 6.2M (@base-ui/react) [28] part of @base-ui/react 1.6.0 (145 kB gz whole lib) [28] 1.6.0 — 2026-06-18 [28]

The install gap is the headline number of 2026. Sonner is not “a bit more popular” than react-toastify — it is ~10× more installed per week (41.4M vs 4.0M) [1] [10], because every project scaffolded through shadcn/ui ⭐ 119k pulls it in: shadcn’s own toast component is formally deprecated in favour of Sonner [29] [30]. Treat downloads as an install-graph signal, not a popularity vote — but the install graph is what determines how much Stack Overflow, LLM training data and third-party wrappers exist for a library.

API surface and ergonomics

All four standalone libraries converge on the same shape: mount one container component at the app root, then call an imperative toast() from anywhere — no context, no prop drilling, callable from event handlers, catch blocks, or non-React code.

  Container Call site
Sonner <Toaster /> [31] toast('msg'), toast.success/error/warning/info/promise/custom [31]
react-toastify <ToastContainer /> [32] toast('msg', {...}), toast.success/error/…/promise [32]
react-hot-toast <Toaster /> [33] toast(), toast.promise, plus useToaster() / useToasterStore() headless hooks [33]
notistack <SnackbarProvider> wrapper enqueueSnackbar() / useSnackbar()
Mantine <Notifications /> inside MantineProvider [34] notifications.show/hide/update/clean [34]
Chakra v3 <Toaster /> + createToaster() [35] toaster.create/update/dismiss/promise [35]
Base UI <Toast.Provider> + <Toast.Viewport> [36] useToastManager().add/update/close/promise, or a global manager via Toast.createToastManager() [36]
MUI Snackbar none declarative only — you hold open state yourself [37]

MUI Snackbar is the outlier and the reason notistack exists at all: it renders one snackbar bound to an open prop, has no queue, and the MUI docs themselves point at notistack for stacking — “With an imperative API, notistack lets you vertically stack multiple Snackbars without having to handle their open and close states” [37]. If you are on MUI and want toasts, you are choosing between hand-rolling a queue, adopting notistack (see maintenance caveat below), or dropping Sonner in next to MUI — Sonner has no MUI coupling.

Feature matrix

Feature Sonner react-toastify react-hot-toast notistack Mantine Chakra v3 Base UI
toast.promise() (loading→success/error) [31] [32] [33] ✗ (manual update) ✗ (manual notifications.update) [34] toaster.promise [35] .promise() [36]
Arbitrary JSX content toast.custom [31] ✓ “bring your own component” [32] toast.custom [33] content ~ (Styles API, not free JSX) [34] ✓ composable subcomponents [35] ✓ fully composable parts [36]
Headless / unstyled mode ✓ headless option [31] ~ (v11 simplified DOM, CSS overridable) [13] useToaster() [33] ~ ~ ✓ unstyled by design [36]
Visible-count cap / queue visibleToasts [31] limit [32] ✓ (per-type limits) maxSnack limit + FIFO queue + priority [34] max, overlap [35] [36]
Stack-and-expand-on-hover UX expand [31] ✗ (list) ✗ (list) ✗ (list) overlap [35] ✓ (CSS-var stacking) [36]
Update an existing toast by id notifications.update [34] [35] ✓ (re-add with same id) [36]
Multiple independent toasters ~ ✓ (containerId) added in 2.6.0 [16] ✓ (multiple createToaster) [35]
Zero CSS import needed since v11 — style tag is injected [13] ✓ (goober CSS-in-JS) ✓ (goober) must import @mantine/notifications/styles.css [34] ✓ (you write the CSS)
CSP nonce support ~ nonce prop (11.1.0) [3] ~ ~ ✓ (Mantine-wide)
Swipe-to-dismiss [31] ✓ (drag) [3] [36]

TypeScript. All seven are TS-native and ship their own declarations — none needs @types/*. Sonner and react-hot-toast are written in TS with fully typed toast.* overloads; react-hot-toast explicitly swapped the deprecated global JSX.Element type for React.ReactElement in 2.5.2, which is exactly the change React 19’s type packages force [16]. react-toastify v11 removed the useToastContainer / useToast hooks from the public surface, so old typed wrappers around them break on upgrade [13].

Accessibility. All of them render an ARIA live region, so this axis is rarely the deciding factor — but it is not free. Sonner’s 4s default auto-dismiss is below what WCAG 2.2.1 (Timing Adjustable) implies for slow readers; raise the Toaster duration if a11y is audited [38]. react-toastify v11 added an ariaLabel prop and an alt+t keyboard shortcut to focus the notification region [13]; Base UI Toast uses F6 to jump to the viewport landmark and configurable low/high live-region priority [36]. Radix’s own Toast primitive has an open, unresolved report that toasts are not announced because the live region resolves to aria-live="off" — a reason to prefer Sonner over hand-rolled Radix toasts even inside a Radix codebase [39].

Maintenance health — the real differentiator

Library Last npm release Last commit pushed Read
react-toastify 2026-04-19 (11.1.0) [3] 2026-04-19 [9] Actively released. Bug-fix-and-feature release only 3 months ago; 72 open issues on a 13.4k-star repo is normal load.
Sonner 2025-08-02 (2.0.7) [1] 2025-12-23 [6] Quiet but not dead. ~11 months without a release, ~7 without a commit — feature-complete single-maintainer project, 52 open issues. ⚠ Bus factor is the risk, not bugs.
react-hot-toast 2025-08-15 (2.6.0) [16] 2025-08-16 [14] Slow. ⚠ 115 open issues — highest absolute count here, and the repo has been untouched for ~11 months. Snyk still grades maintenance “Sustainable” on release cadence [40].
notistack 2025-01-18 (3.0.2) [5] 2026-03-31 [18] Effectively legacy. 18 months without a published version. It still works (peer deps admit React 19, v3 dropped its MUI dependency and now ships on goober), and 1.4M weekly installs are mostly existing MUI codebases. Not a greenfield pick.
Mantine / Chakra / MUI / Base UI 2026-06-28 / 2026-06-10 / 2026-07-03 / 2026-06-18 [22] [24] [26] [28] this month Backed by the design system’s release train — the toaster gets maintained as long as the design system does.

Note the inversion of the popularity narrative: the library everyone installs (Sonner) has the quietest repo, and the library the blogosphere calls legacy (react-toastify) has the newest release. Neither fact should flip your decision on its own — a toast library is a small, finished problem — but if you need a fix landed upstream this quarter, react-toastify is the one whose maintainer is currently shipping.

Design-system natives: use them if you already pay for them

  • Mantinenotifications.show() from anywhere, limit with a real FIFO queue and a priority field that can bump a notification into a visible slot ahead of older ones; notifications.update() covers the loading→done pattern manually since there is no promise() helper. ⚠ It is the only option here that silently misbehaves without a CSS import (@mantine/notifications/styles.css, after core styles) [34]. +5.5 kB gz on top of @mantine/core [22].
  • Chakra UI v3createToaster() + toaster.create(); the most complete built-in of the four: toaster.promise(), max, overlap stacking, pauseOnPageIdle, composable Title/Description/ActionTrigger parts, built on Ark UI [35]. Sensible only if Chakra is already your system — @chakra-ui/react is 293 kB gz as a whole package (tree-shakeable, but the design-system tax is real) [24].
  • MUI — Snackbar is a controlled component, not a toast system [37]. Pair with notistack (aging) or bolt Sonner on.
  • shadcn/ui — there is no shadcn toast any more. The toast component page carries “The toast component has been deprecated. Use the sonner component instead.” [29], tracked in issue #7120 [30]; sonner is now a first-class shadcn component with a pre-themed <Toaster /> [2]. This single decision is what produced Sonner’s install numbers.
  • Base UI (the MUI team’s headless successor to Radix) — Toast is a genuine competitor now that Base UI is stable: useToastManager() with add/update/close/promise, a createToastManager() for firing toasts outside React, swipe-to-dismiss, F6 landmark navigation, fully unstyled [36]. @base-ui/react reached 1.6.0 in June 2026 and does 6.2M weekly installs [28]. Pick it when you want to own every pixel and are already headless-first; skip it if you just want a toast that looks good today.

Reach for X when Y

When… Reach for
Greenfield React app, no strong design system, you want good defaults in 10 minutes Sonner — 0 deps, 9.2 kB, toast.promise, stack-and-expand, shadcn-native [7] [2]
You use shadcn/ui Sonner — there is no alternative in-system; toast is deprecated [29]
Bundle budget is the hard constraint (marketing site, embed, widget) react-hot-toast — 4.7 kB gz, ~half of Sonner; ⚠ accept a slow-moving repo [4] [17]
You need deep customisation (custom progress bar, notification centre, CSP nonce, containerId routing) or you want the maintainer who is actually shipping react-toastify v11 [13] [3]
You already ship Mantine or Chakra v3 the built-in toaster — ~0 marginal bytes, matches your theme [34] [35]
You already ship MUI Sonner alongside MUI, or notistack only if you’re already on it — MUI’s Snackbar has no queue [37]
Headless-first codebase, you style everything Base UI Toast [36]
Existing notistack codebase Stay — it works on React 19 — but ⚠ plan a Sonner migration; no release since Jan 2025 [5]
Greenfield + notistack Don’t.

Migrating away from a toast library is a mechanical find-and-replace of toast() call sites plus one root component — the switching cost is close to zero, which is exactly why you should not agonise over this decision. Take Sonner; revisit if a constraint bites.

Citations · 41 sources

Click the Citations tab to load…