Decision. Default to Sonner ⭐ 12.6k (Jul 2026) — shadcn/ui deprecated its own Radix-based toast and now tells you to use Sonner instead [1]. Build on a primitive only if one of the four conditions below holds — and if so, the primitive is Base UI Toast ⭐ 10.3k, stable since 1.0 on 11 Dec 2025 [2], or Zag.js / Ark UI if you ship to more than one framework [3].
The primitive layer, ranked
| Primitive | Status (Jul 2026) | Free out of the box | You still build |
|---|---|---|---|
| Base UI Toast ⭐ 10.3k | Stable (1.0 Dec 2025, v1.6.0 Jun 2026) [2] | Swipe-to-dismiss, hover/focus timer pause, stacking + limit, aria-live priority, F6 landmark focus, promise() / update() by id [4] |
All CSS, animations, dismiss-button UI, per-type styling, collision boundaries [4] |
| Zag.js / Ark UI ⭐ 5.2k / ⭐ 5.3k | Active, React + Vue + Solid + Svelte parity | Priority queue with max, pause on hover/focus/page idle, screen-reader wiring, toaster.promise() [3] |
Same as above; swipe not documented [3] |
| Radix Toast ⭐ 19.1k | ⚠ Alive but a dead end — still shipping (30 Jun 2026 release fixed a Toast close-timer memory leak) [5], yet post-WorkOS-acquisition “update velocity has slowed” and Base UI “is now the more actively maintained primitive layer” [6] — and its biggest consumer dropped it [1] | Don’t start here in 2026 | |
| React Aria Toast ⭐ 15.7k | ✗ Still alpha; maintainer: “we just haven’t had priority for it” [7] | Best-in-class a11y semantics | Everything else, on an unstable API |
Base UI is the credible successor by construction: it’s built by “the creators of Radix, Material UI, and Floating UI” — Colm Tuite (Radix) included [8].
What you actually pay
The hard parts — ARIA politeness levels, the queue state machine, hover-pause timers, swipe gestures, focus restoration — are not what you save by taking Sonner. Base UI ships all of them [4]. What Sonner buys you is the unglamorous half: viewport CSS, enter/exit transitions, stack offsets, close-button markup, per-type variants. That’s a day of work, not a week — and you’d write most of it anyway to hit your tokens.
Decision rule — go primitive if ≥1 holds
- Multi-framework design system → Zag.js/Ark, the only option with React/Vue/Solid/Svelte parity from one machine [3].
- Deep theming is a recurring cost. Overriding Sonner means nullifying utility classes, and with
unstyled“some internal elements are not directly reachable” [9]. - You already standardised on Base UI elsewhere → one a11y vendor, one motion system, zero extra bundle.
- Anchored toasts or custom queue semantics (positioner + arrow, priority ordering, upsert-by-id) that Sonner doesn’t expose [4].
None of the four? Ship Sonner. A hand-rolled toast is a permanent a11y liability for a component users see for four seconds.