mrkeyoor.com_
Wed 23 Sept 00:35 UTC
npmWeb Frontendupdated 22 Sept 2026

react-hot-toast review

react-hot-toast 2.6.0 keeps transient React notifications in a module-level store and renders them through `<Toaster>`, `<ToastBar>`, or headless hooks. It handles plain, success, error, loading, custom JSX, and promise states with configurable timing, position, style, icon, and ARIA properties. Version 2.6 adds multiple independent toaster IDs and minifies its inlined CSS during the build. Our package-wide browser build reached 20.3 KB minified and 7.8 KB gzipped, including more than the small core cost often quoted for selected entry points.

Verdict

react-hot-toast 2.6.0 installed in 1.4 seconds and produced a 7.8 KB gzipped package-wide bundle in our sandbox with 0 audit findings. It is a good fit for disposable React feedback, not for a notification inbox or errors users must revisit.

We installed it

Lab card: what happened when we installed react-hot-toastScreenshot of react-hot-toast documentation
Install✓ · 1.4s10 packages on disk · 10 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser7.8 KBgzipped (20.3 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does react-hot-toast install cleanly?

Yes. In a fresh container with an empty cache, npm install react-hot-toast finished in 1 seconds, leaving 10 packages and 10 MB on disk. npm audit reported no known vulnerabilities.

How much does react-hot-toast add to a browser bundle?

7.8 KB gzipped (20.3 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does react-hot-toast work with both ESM and CommonJS?

Yes. Both import 'react-hot-toast' and require('react-hot-toast') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does react-hot-toast include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

react-hot-toast or sonner: which should you use?

sonner: Use it for modern stacked-toast presentation and an API common in current React design systems. react-hot-toast 2.6.0 installed in 1.4 seconds and produced a 7.8 KB gzipped package-wide bundle in our sandbox with 0 audit findings.

When should you not use react-hot-toast?

The application is not React; the standard renderer declares React and React DOM peers

API stability4/5The 2.x line retains the central `toast` function, Toaster, ToastBar, and headless hooks. Version 2.6 added `toasterId` routing without replacing the default path, and the package exposes explicit CommonJS, ESM, type, and headless entries. Custom renderers depend on more lifecycle details than simple `toast.success()` calls, so another major would carry greater risk for headless consumers.
Docs5/5The official site separates references for toast calls, Toaster, ToastBar, store access, headless hooks, styling, and multiple toasters. It states the 1,000ms removal delay, infinite loading duration, promise width issue, ARIA defaults, and offset calculations. Framework-specific server component advice is limited, but the API and lifecycle details needed to avoid stuck or duplicate notifications are documented.
Maintenance3/5npm published 2.6.0 on 2025-08-15, and GitHub records the last push one day later. That release added multiple toasters and minified inlined CSS, so it was substantive. The project is not archived and has 10,969 stars, while GitHub showed 143 open issues and pull requests. A focused package can remain stable without weekly commits, though the issue queue and year without a push justify watching releases.
Ecosystem5/5npm counted 3,737,616 downloads in the week ending 2026-08-24. React 16 and newer are accepted as peers, bundled declarations cover TypeScript, and separate standard and headless exports support both ready-made web UI and custom renderers. The imperative function appears in many React integrations, but its module-level store also means tests and microfrontends must define ownership rather than receiving isolation from a provider.

Use it if

  • A React application needs attractive transient feedback with one root renderer
  • Promise state should update one toast from loading to success or failure
  • Event handlers outside component render functions need an imperative toast call
  • A custom renderer or React Native target can use the headless store and lifecycle hooks
Skip it if

Setup reality

We installed react-hot-toast 2.6.0 in 1.4 seconds. The fresh sandbox left 10 packages using 10 MB on disk; the package itself was 280 KB unpacked with 2 direct dependencies and 2 peers. npm audit found 0 known vulnerabilities. The package is CommonJS with an exports map, while both require() and ESM import worked. TypeScript declarations ship in the package.

React and React DOM are peer dependencies. Mount one <Toaster /> for the default store, usually near the root. Next.js App Router needs that renderer inside a client component because it uses hooks and browser layout. There is no provider, stylesheet import, account, or config file. The standard entry uses goober; react-hot-toast/headless leaves rendering to you.

Our browser build measured 20.3 KB minified and 7.8 KB gzipped. Dismissed items remain mounted for an exit animation and are removed after 1,000ms by default; toast.remove() skips that delay. A manual loading toast has infinite duration, so every branch must update, dismiss, or remove its ID. toast.promise() returns the original promise and does not replace application-level error handling.

Version 2.6 can route calls to separate renderers through matching toasterId values. That helps embedded surfaces, but a missing ID silently targets the default toaster. All toast types default to role=status with polite announcements, including errors. Use assertive ARIA sparingly, and keep validation or destructive-action failures inline where users can find and act on them after the toast disappears.

Patterns

Render the default toast outlet once mount-toaster

import { Toaster } from 'react-hot-toast'

export function App() {
  return <>
    <Routes />
    <Toaster position="top-right" />
  </>
}

One matching Toaster must be mounted before calls become visible; mounting one per route creates duplicate outlets.

Emit success and error messages show-feedback

import toast from 'react-hot-toast'

toast.success('Profile saved')
toast.error('Could not save profile')

Both types announce politely by default. Important failures still need visible inline text and a recovery action.

Map one promise across 3 states track-promise

await toast.promise(saveProfile(values), {
  loading: 'Saving profile...',
  success: (profile) => `Saved ${profile.name}`,
  error: 'Save failed',
})

The returned promise is the original operation, so a rejection still needs normal application error handling.

Finish a manually started loader update-loading-toast

const id = toast.loading('Publishing...')
try {
  await publish()
  toast.success('Published', { id })
} catch (error) {
  toast.error('Publish failed', { id })
}

Loading duration is infinite; reuse the same ID in every completion branch or the spinner stays on screen.

Upsert one logical notification prevent-duplicates

toast.success('Copied to clipboard', {
  id: 'clipboard-copy',
})

A stable ID replaces the existing toast. Choose IDs per event so unrelated feedback never overwrites it.

Dismiss with the exit animation dismiss-toast

const id = toast('Connection restored')
setTimeout(() => toast.dismiss(id), 1000)

`dismiss()` waits the default 1,000ms removal delay; `remove(id)` deletes the DOM node immediately.

Set durations and urgent ARIA behavior set-global-options

<Toaster toastOptions={{
  duration: 5000,
  success: { duration: 2500 },
  error: { ariaProps: { role: 'alert', 'aria-live': 'assertive' } },
}} />

Per-call options override these defaults. Reserve assertive announcements for messages that require immediate attention.

Target a named sidebar outlet route-toaster

<Toaster toasterId="sidebar" containerStyle={{ position: 'absolute' }} />

toast('Sidebar updated', { toasterId: 'sidebar' })

Both sides need the same ID in version 2.6. Omitting it sends the notification to the default outlet.

Alternatives

PackageRegistryPick it when
sonnernpmUse it for modern stacked-toast presentation and an API common in current React design systems.
react-toastifynpmUse it when built-in transitions, progress controls, and a larger configuration surface are useful.
notistacknpmUse it in Material UI applications that want provider-based snackbar queues.
@radix-ui/react-toastnpmUse primitives when markup and visual styling must remain under your design system's control.

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.