← Default view
Scout · Expedition · 13 Jul 2026 5 angles · 119 sources A broadside on React toasts
The contradiction, up front

The library everyone installs
and the library that is
actually accessible
are not the same library.

What the ecosystem installs
41M
weekly installs — Sonner
Polite-only. There is no assertive path in the source, so toast.error() never interrupts a screen reader. Auto-dismisses at 4 s.
✕ announcement model wrong
What announces correctly
≈0
Base UI Toast · React Aria
Live region mounted before the message arrives. A non-modal dialog for the buttons. A landmark hotkey to reach it. Nobody installs them.
✓ announcement model right
The literal question — is toastr still a thing? — has a one-word answer: no. Everything interesting is in what replaced it, and there the five angles disagree in a way worth naming.
Thesis 01
role="status" toastr · v2.1.4
toastr is toast
Last published December 2017. Final commit June 2018. Still a hard dependency on jQuery — in a React app, in 2026.[1] This is not a library with a slow release cadence. It is a library that stopped.
GitHub repository card for CodeSeven/toastr showing 12k stars and 119k dependent repositories
Exhibit A — 12k stars, 119k repos still using it, zero commits since 2018
Two slices of badly burnt toast on a white plate
Exhibit B — the state of the art, 2017

119,000 repositories still depend on it. That number is the migration backlog, not a health signal — and it is the only thing in this expedition where the recommendation is unambiguous. Move. There is no counter-argument to make on behalf of a dead jQuery plugin.

Thesis 02
aria-live="polite" ecosystem
Distribution decided
this category.
Not merit.
A 10× install gap is not a 10× quality gap. It is one default, in one scaffolding tool.[2]
41M / wk
~4M / wk — 10× behind, and shipping harder
Radix Toast
collateral — abandoned by its largest consumer
Thesis 03
aria-live="polite" npm
The most-installed
library has the
quietest repo.
Install count is a lagging indicator of one scaffolding decision. It is not a measurement of maintenance — and here it points the wrong way.
Library
Weekly installs
Last release
What that means
41M
Aug 2025
The default everyone ships. Nearly a year without a release.
~4M
Apr 2026 · v11.1.0
CSP-nonce support and a React 19 fix. The one actually being worked on.[5]
GitHub repository card for fkhadra/react-toastify
Exhibit C — react-toastify, 4M installs, still shipping in 2026

If you already run react-toastify, the case for churning a working integration is thin: it is alive, it ships, and it does not owe Sonner a migration. The 10× gap flatters the wrong axis.

Read the install count for what it is — a record of what a scaffolding tool typed for you in 2024 — and the ranking stops looking like a quality ordering.

Thesis 04
aria-live="polite" toast.error("Payment failed")
Popularity bought
an accessibility bill.
There is no assertive path in Sonner's source. toast.error() is announced politely — which means: queued behind whatever the screen reader is already saying, and then gone. The toast auto-dismisses at 4 s, whether or not it was ever read.
Screen-reader transcript · the same 4 seconds
0.0s
"…row 14, column 3, expiry date, edit, blank…"
0.4s
▸ toast mounts. Polite. Waits its turn.
2.1s
"…column 4, CVC, edit, blank…"
4.4s
▸ toast unmounts. The payment failure was never spoken.

A 4-second auto-dismiss with no way to extend it is a plain WCAG 2.2 SC 2.2.1 failure — timing adjustable.[6] The correct model is not subtle and it is not new: mount the live region before the message arrives,[7] use a non-modal dialog for anything with a button, give the user a landmark hotkey to reach the thing.

The libraries that implement it — Base UI and React Aria — are the two nobody installs. That is the sharpest contradiction in this expedition: the recommended default and the accessible default are different libraries.

Base UI documentation card
Exhibit D — Base UI Toast, stable since December 2025, ≈nobody installs it
And one more thing
"use client" server boundary
Nobody solves
the server boundary.
"RSC-compatible" is table stakes and means less than it sounds.

All three major libraries ship "use client" at the top of their dist bundle,[8] so <Toaster /> drops into an App Router layout unchanged. None of them exposes a server-callable queue. A server mutation can only describe a toast and hand it across — and if the action calls redirect(), the caller unmounts before any return value arrives,[9] forcing a flash-cookie round trip you write yourself.

React Router 7 has had session.flash() for exactly this, all along.[10]

Take Sonner.
Know what
you are buying.

It is the right default — the ergonomics are genuinely good and the ecosystem has already voted with its scaffolding. But it is polite-only, its repo is the quietest of the group, and it will not fire a toast from a server action for you.

If you ship to a normal a11y bar

Install Sonner, raise the dismiss duration off 4 s, and accept that error toasts will not interrupt. Do not churn a working react-toastify integration to get here.

If you ship to a public-sector or enterprise a11y bar

Budget for the fixes — or build on Base UI Toast, stable since December 2025,[11] and write the CSS yourself. It is the only primitive in 2026 that is both stable and feature-complete.

In 2026 no React toast library offers both the ergonomics and the correct announcement model.

And the standard itself has not settled: the W3C is still arguing about whether SC 2.2.1 even applies to toasts. The issue has been open since 2019.[12] Until it closes, every team ships a judgment call and calls it a default.

w3c/wcag #976 · open · 2019 → today