WingoUI
ComponentsTemplatesDocsChangelogBlogAI agents
ThemePricing
  1. Home
  2. Blog
  3. Comparisons and alternatives
  4. Sonner Alternative for React: 4 Toast Libraries Compared
  1. Blog
  2. Comparisons and alternatives
  3. Sonner Alternative for React: 4 Toast Libraries Compared
Comparisons and alternatives
Comparisons and alternatives

Sonner Alternative for React: 4 Toast Libraries Compared

SR
Serban Rusu · Founder of Wingo UI
Oct 9, 2026 · 11 min read

On this page

0%
  1. What is the best Sonner alternative for React?
  2. How do Sonner, react-hot-toast and React-Toastify compare?
  3. Sonner vs react hot toast: which one should you use?
  4. When is React-Toastify the better pick?
  5. What does "shadcn toast" mean in 2026?
  6. What changes on a phone?
  7. How do the toasts sound to a screen reader?
  8. When should you skip the toast and use an inline alert?
  9. What does a source-owned toast give you?
  10. How do you move from Sonner to the Wingo UI Toast?
  11. Where should you start?
  12. FAQ
    1. What is the best Sonner alternative for React?
    2. Is Sonner better than react-hot-toast?
    3. Does shadcn/ui still use Sonner for toasts?
    4. Which React toast library is the smallest?
    5. Are toast notifications accessible to screen readers?

TL;DR

The right Sonner alternative depends on what Sonner does not do for you, and if nothing is wrong, keep it: it is by far the most downloaded of the four toast libraries compared here and has a stack, swipe and promise toasts built in. Pick react-hot-toast for the smallest bundle (4.8 kB gzip) and a headless hook, or React-Toastify for progress bars, a queue limit and a notification history. Pick a source-owned toast, such as the free Wingo UI Toast, when you need to change how the stack behaves on phones, for screen readers or in your design system.

Published Oct 9, 2026

You go looking for a Sonner alternative when something about the toast stops fitting: the bundle, a design system that fights its stylesheet, an accessibility review, or action buttons that are hard to hit on a phone. Sonner is still the default React toast for good reasons, so leaving it should fix a specific problem. This comparison puts Sonner next to react-hot-toast, React-Toastify and a source-owned toast on the API, the stack, swipe, screen readers, phones and bundle size, checked in October 2026 against each package's published code and docs.

We build Wingo UI, whose free Toast is the source-owned option here, so read this as a vendor's comparison with sources; it says where each of the others is the better pick. More head to head comparisons live under Comparisons and alternatives, and the guide to shadcn alternatives compares whole component libraries.

What is the best Sonner alternative for React?

The best Sonner alternative depends on what you are leaving for:

  • A smaller bundle and your own markup: react-hot-toast. It measured 4.8 kB gzip in our build, half of Sonner, and its useToaster hook lets you render every toast yourself.
  • More features built in: React-Toastify. Progress bars, a queue limit, toast.update, a stacked mode, RTL and a notification history add-on, with no extra packages.
  • Behavior you can change: a toast whose source lives in your repository, such as the free Wingo UI Toast. It keeps a Sonner-style toast() API, and the stack, the timers and the phone layout are code you can edit.
  • No problem to fix: stay on Sonner. It is the most downloaded React toast notification library of the four by a wide margin, and shadcn/ui installs it for Radix and React Aria projects.

How do Sonner, react-hot-toast and React-Toastify compare?

The table reads the latest version of each package on npm as of October 9, 2026. Sizes are our own measurement: each library's toaster component and toast function bundled with esbuild 0.28, minified, React left external, then gzipped. Sonner and React-Toastify inject their CSS from JavaScript, so their numbers include the styles. Downloads are npm's count for October 1 to 7, 2026.

Sonner (opens in a new tab)react-hot-toast (opens in a new tab)React-Toastify (opens in a new tab)Wingo UI Toast
Version2.0.8, Aug 9, 20262.6.1, Sep 16, 202611.1.0, Apr 19, 2026Toast 1.0.0 in registry 1.7.0, Oct 8, 2026
LicenseMITMITMITFree item, Wingo UI license
Weekly npm downloads50.8 million3.7 million2.9 millionNot on npm, copied by the CLI
Size, min + gzip9.6 kB4.8 kB9.8 kB12.2 kB, plus motion if you lack it
Default position and timebottom-right, 4 stop-center, 2 s for success, 4 s for otherstop-right, 5 sbottom-right, 4 s
StackCollapsed, fans out on hover, 3 visibleA listA list, or collapsed with stackedCollapsed, fans out on hover or tap, 3 visible
Swipe to dismiss45px or a flickNoneTouch only, 80% of the widthTouch and mouse, a quarter of the toast or a flick
KeyboardAlt+T focuses the list, Esc collapses itNoneAlt+T focuses a toast and pauses, Esc resumesAlt+T focuses the newest toast, Esc dismisses it
Screen readerOne polite region for all toastsEach toast polite statusEach toast role="alert"Each toast polite status, errors alert
Phone layoutFull width below 600pxNone built inFull width below 480px, safe areasFull width below 768px, safe areas
Reduced motionTransitions offFades instead of slidingNo rule in the packageFades instead of sliding
Your own markupunstyled, toast.customreact-hot-toast/headlessreact-toastify/unstyledEdit components/ui/toast.tsx

The Wingo UI size needs a footnote: in most apps it is the heaviest of the four, because it animates with motion. In a shadcn-style project that already ships tailwind-merge, lucide-react and Radix, it adds 57.6 kB, motion included. If that app already uses motion too, it adds only its own 12.2 kB, and with nothing shared it is 69 kB, seven times Sonner. Its styles are Tailwind classes that compile into your app's stylesheet, so they are not in these numbers.

Sonner vs react hot toast: which one should you use?

Use Sonner if you want a stack, swipe and action buttons without writing them. Use react-hot-toast if you want the smallest package and plan to render toasts your own way. The two look alike at the call site until you need a button:

tsx
// sonner: action and cancel are options
import { toast } from "sonner";
export function onDelete(restore: () => void) {
toast("Listing deleted", {
description: "City bike, Trek FX 2",
action: { label: "Undo", onClick: restore },
});
}
tsx
// react-hot-toast: no action option, so the button is your markup
import toast from "react-hot-toast";
export function onDelete(restore: () => void) {
toast((t) => (
<span>
Listing deleted
<button
onClick={() => {
restore();
toast.dismiss(t.id);
}}
>
Undo
</button>
</span>
));
}

Beyond buttons, react-hot-toast lists toasts instead of stacking them, has no swipe and no keyboard handling, and pauses its timers only on mouse enter and leave, not for keyboard focus or a background tab. Success toasts default to 2 seconds, which is short for an Undo. Its strength is the headless entry: useToaster from react-hot-toast/headless hands you the toasts plus startPause, endPause and calculateOffset, the right shape if you want full control of the markup and will write the gestures yourself.

Sonner gives you polished defaults: a 356px stack, swipe in the directions its position allows, toast.promise, richColors and a close button, with timers that pause while you hover, while you swipe and while the tab is in the background. Its look comes from its own stylesheet, so matching a design system means CSS variables and classNames, or unstyled and your own markup.

When is React-Toastify the better pick?

Pick React-Toastify when you need features the others leave out: a progress bar on every toast, on by default, and a controlled progress value for uploads. limit holds extra toasts in a waiting queue, toast.update(id, options) changes a toast in place, stacked collapses the list, and the useNotificationCenter add-on keeps a history of toasts for an inbox. It handles RTL and positions its container with env(safe-area-inset-*) on phones.

Its defaults are the loudest of the four: a close button and a progress bar on every toast, 5 seconds on screen, and role="alert" on each toast, so screen readers interrupt the user for a "Saved" message unless you pass role="status". We found no prefers-reduced-motion rule in the 11.1.0 package, so the default Bounce transition plays for everyone; pass transition={Slide} or your own cssTransition if that matters to you.

If those defaults or the styling are why you want a React Toastify alternative, Sonner is the closest swap for the call sites (toast.success, toast.error, toast.promise). The main rename is the promise's loading message: React-Toastify calls it pending and Sonner calls it loading. A history with read state is an inbox, a different job: Wingo UI keeps it in a separate Notification Center with a bell and an unread count.

What does "shadcn toast" mean in 2026?

It depends on the project's base. Since July 2026 new shadcn/ui projects start on Base UI, and for those npx shadcn@latest add toast installs a Toast built on Base UI primitives (opens in a new tab), called with toast.add({ title, description }) and toast.promise. In Radix and React Aria projects, the old Toast is marked deprecated and the docs point to Sonner (opens in a new tab): npx shadcn@latest add sonner writes a components/ui/sonner.tsx that wraps the package, maps its colors to your --popover and --border tokens and reads the theme from next-themes.

So the shadcn toast in a Radix project is Sonner with your colors: you own a short wrapper, and the stack, timers and swipe stay in node_modules/sonner. The Base UI version hands you more of the markup, with behavior from Base UI's Toast parts. Per the Base UI docs (opens in a new tab), that means a 5 second default timeout, a limit of 3, swipe down or right, a priority: "high" option for urgent announcements, and F6 to move focus into the toast region.

What changes on a phone?

The phone is where these libraries differ most, on four points:

  • Width. Sonner spans the screen below 600px with 16px gutters (mobileOffset). React-Toastify spans it below 480px with square corners. react-hot-toast has no phone layout: its toasts cap at 350px and sit 16px from the edges.
  • Buttons. Sonner's default action and cancel buttons are 24px tall, exactly WCAG 2.2's minimum target size, and its close button is 20px, under it. All of them are far from the 44pt Apple recommends for iOS controls; our guide to minimum touch target size has the numbers.
  • Safe areas. React-Toastify positions its container with the safe area insets. Sonner and react-hot-toast do not, so with viewport-fit=cover a bottom stack can sit on the iPhone home indicator until you add the inset to the offset yourself. Tailwind safe area insets shows the pattern.
  • Swipe. Sonner dismisses after 45px of travel or a quick flick. React-Toastify swipes on touch only by default and wants 80% of the toast's width. react-hot-toast has no swipe.

We built the Wingo UI Toast around that list. Below 768px toasts span the width with 16px gutters, each edge uses max(env(safe-area-inset-*), 16px), and mobilePosition="top" moves them clear of a bottom tab bar. Action and close buttons look 32px tall and keep a 44px hit area on touch screens. With no hover on a phone, a tap fans out the stack.

Hover the stack to fan it out (tap it on a phone), then swipe the front toast toward the edge. Press Failed payment, then Retry: the same toast turns into a loading state and then a success
$ npx wingo-ui@latest add toast
FreeToast docs

How do the toasts sound to a screen reader?

All four announce through ARIA live regions; the difference is what gets interrupted. A polite announcement waits until the screen reader finishes speaking. An assertive one, which role="alert" implies, cuts in.

  • Sonner wraps every toast in one <section aria-live="polite"> labeled "Notifications alt+T". A failed payment is announced as politely as "Copied".
  • react-hot-toast gives each toast role="status" and aria-live="polite", and you can switch a single toast to alert through its ariaProps option.
  • React-Toastify gives each toast role="alert", so every toast interrupts unless you change the role.
  • Wingo UI makes each toast its own polite status and switches errors, and any toast sent with important: true, to role="alert".

For the keyboard, Sonner's Alt+T focuses the list and Escape collapses it, React-Toastify's focuses a toast and pauses every timer until Escape, and react-hot-toast has none. In the Wingo UI Toast, Alt+T (Option+T on a Mac) focuses the newest toast, Tab walks through its buttons, Escape dismisses the focused toast, and timers pause while keyboard focus is inside, so there is time to reach Undo.

When should you skip the toast and use an inline alert?

Skip it when the message has to be read or acted on. A declined card, a form that failed to save, or a session about to expire need a message that stays next to the problem. Toasts time out, sit far from the field that caused them, and on a phone they can cover the submit button. Use an inline alert for those and keep toasts for confirmations, progress and quick undos. The free Alert follows the same split for screen readers: danger and warning tones use role="alert", the others role="status".

A declined card belongs next to the Pay button: press Try again and the alert collapses, then press Pay to see it expand back in
$ npx wingo-ui@latest add alert
FreeAlert docs

What does a source-owned toast give you?

A source-owned toast puts the whole component in your repository: the store, the stack, the gesture and the markup. You review it like the rest of your code, and nothing changes under you on npm update. The cost is that upstream fixes reach you only when you pull them. The Wingo UI Toast is free; install it with the CLI:

bash
npx wingo-ui@latest add toast

That writes components/ui/toast.tsx plus the button, the spinner and the hooks and helpers it uses. Mount the Toaster once, next to the app:

tsx
// app/providers.tsx
"use client";
import type { ReactNode } from "react";
import { Toaster } from "@/components/ui/toast";
export function Providers({ children }: { children: ReactNode }) {
return (
<>
{children}
<Toaster richColors mobilePosition="top" />
</>
);
}

Then call toast from anywhere, even outside React or before the Toaster mounts:

tsx
import { toast } from "@/components/ui/toast";
export function onDelete(restore: () => void) {
toast("Listing deleted", {
description: "City bike, Trek FX 2",
action: { label: "Undo", onClick: restore },
});
}
export async function publishListing(publish: () => Promise<{ price: string }>) {
// returns the original promise: await gives you the data or throws the error
return toast.promise(publish, {
loading: "Publishing the listing…",
success: (data) => `Published for ${data.price}`,
error: "Could not publish the listing",
});
}

Beyond those call sites, the file gives you:

  • Updates by id. Calling toast.loading("Uploading 3 photos… 2/3", { id: "upload" }) again updates the toast in place. A new type with the same id, such as toast.success, starts it over, so the loading toast's Infinity duration never sticks to the success.
  • Your tokens. The surface uses bg-popover and your theme's status tones, so dark mode needs no theme prop. Visual props such as radius, width and richColors can also be set app-wide through UIProvider defaults.
  • Updates that keep your edits. npx wingo-ui@latest update merges a new release into the file you changed, as the updates docs describe.

The trade-offs, stated plainly. It is younger than the three packages, and Sonner has years of bug reports behind it. It costs more bytes than any of them, even in an app that already uses motion. In a shadcn project created with a Base UI style, install it with the Wingo UI CLI instead of shadcn add, because that style rewrites asChild, which the button relies on. The Notification Center is part of Wingo UI Pro; the Toast and the Alert are free.

How do you move from Sonner to the Wingo UI Toast?

Most call sites only change the import. The API follows Sonner's: toast, toast.success, error, warning, info and loading, toast.promise, toast.custom, toast.dismiss, the action, cancel and toasterId options, and the position, expand, visibleToasts, duration, richColors and closeButton props keep their names and defaults. The differences:

SonnerWingo UI Toast
import { toast } from "sonner"import { toast } from "@/components/ui/toast"
hotkey={["altKey", "KeyT"]}hotkey="alt+t"
<Toaster id="editor" /> for a second toaster<Toaster toasterId="editor" />
toast.promise(...).unwrap() for the resulttoast.promise(...) returns the original promise
theme prop, or next-themes in the shadcn wrapperNone; the surface uses your tokens
event.preventDefault() in an action keeps the toast openThe same, or keepOpen: true on the action
mobileOffset below 600pxmobileOffset below 768px, plus mobilePosition
toast.message, toast.getHistoryNot available; useToasts() returns the toasts on screen

If you used the shadcn wrapper, delete components/ui/sonner.tsx, point the Toaster import at @/components/ui/toast, and replace from "sonner" in the files that call toast. Then drop any theme prop from the Toaster and the .unwrap() after promise toasts, which TypeScript flags.

Where should you start?

If Sonner works and nobody has complained, keep it. If the complaint is about phones, screen readers or a design system that will not bend, try a source-owned toast: run npx wingo-ui@latest add toast, which is free and needs no account, swap the import on a few call sites, and open the app on your own phone.

Components in this post

  • Toast

    Toast notifications: a Toaster mounted once and a toast() you call from anywhere, stacked, swipeable and paused while you read.

    Free
  • Alert

    An inline message about a page or a section, from a failed payment to a maintenance banner, in three variants and six tones.

    Free

FAQ

What is the best Sonner alternative for React?

It depends on why you are leaving. react-hot-toast is the smallest and has a headless hook, React-Toastify has the most built-in features, and a source-owned toast like the free Wingo UI Toast keeps a Sonner-style API while every behavior lives in a file you can edit.

Is Sonner better than react-hot-toast?

Sonner does more out of the box: a collapsed stack, swipe to dismiss, action and cancel buttons, a promise toast and an Alt+T shortcut. react-hot-toast is about half the size at 4.8 kB gzip in our build and ships a headless useToaster hook, but it has no swipe, no keyboard shortcut and no built-in action buttons.

Does shadcn/ui still use Sonner for toasts?

It depends on the project's base. In Radix and React Aria projects the old Toast is deprecated and npx shadcn@latest add sonner installs a short wrapper around the sonner package. In Base UI projects, the default for new projects since July 2026, npx shadcn@latest add toast installs a Toast built on Base UI with a toast.add() API.

Which React toast library is the smallest?

react-hot-toast, at 4.8 kB minified and gzipped in our esbuild measurement in October 2026. Sonner came to 9.6 kB and React-Toastify to 9.8 kB, both including the CSS they inject from JavaScript.

Are toast notifications accessible to screen readers?

They are announced through ARIA live regions, but the libraries differ in urgency: Sonner announces everything politely, React-Toastify marks every toast role="alert" by default, and react-hot-toast and the Wingo UI Toast let single toasts interrupt. Anything the user must act on belongs in an inline alert, because toasts time out.

  • Toast
  • Sonner
  • Comparisons
  • React
  • Accessibility
  • Mobile UI

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu is the founder of Wingo UI. He builds the component library, its CLI and its MCP server, and writes about React interfaces that work well on phones and with AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Mobile UI in React

Tailwind Safe Area Insets: Bottom Bars, FABs and Toasts

A Tailwind safe area guide for v4: opt in with viewport-fit=cover, pad bars with env(safe-area-inset-bottom) and keep FABs and toasts off the home indicator.

SRSerban Rusu·Oct 9, 2026·12 min read
Comparisons and alternatives

14 shadcn Alternatives in 2026: Price, Mobile and MCP

14 shadcn alternatives checked in October 2026: free and paid UI libraries by license, price, mobile behavior and MCP support, with a pick per use case.

SRSerban Rusu·Oct 9, 2026·19 min read
Comparisons and alternatives

Best React Component Library for Mobile in 2026: 9 Compared

The best React component library for mobile web apps in 2026: 9 libraries checked at 390px for bottom sheets, touch targets, safe areas and gestures.

SRSerban Rusu·Oct 9, 2026·12 min read
Newsletter

Get new posts by email

New guides, tutorials and comparisons from the Wingo UI blog, sent when they are published.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components. Copy the source, make it yours, and let your coding agent build with it.

ComponentsTemplatesPricingBlogTheme

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities
Wingo UI