npm sonner-native 0.25.0
Release 0.25.0

5 hours ago

A big release. Stacking toasts, a New Architecture–only rewrite of measurement, an external state store, and a full migration to pnpm.

⚠ BREAKING CHANGES

  • React Native New Architecture is required. Toast height measurement now uses synchronous useLayoutEffect + getBoundingClientRect(). The legacy onLayout fallback was removed — old architecture builds are no longer supported.

Features

  • Stacking toasts. New iOS-style stack: incoming toasts pile on top of each other with scale/translate animations instead of pushing siblings out. Tap the stack to expand into a list, tap outside to collapse. Heights are measured per-toast so stacks of different-sized toasts line up correctly.
    • enableStacking prop on <Toaster> (default: false)
    • gap prop controls spacing between toasts when expanded
    • Works at all positions; bottom and center stack downward-mirrored
  • Reduce Motion support. When the OS Reduce Motion setting is on, entrance/exit animations are skipped.
  • Promise toasts inherit styles. success / error style overrides on a promise toast now flow through to the resolved/rejected state.

State management rewrite

The toast store moved out of React state into an external observable store. <Toaster> and the toast() API now subscribe through a stable handler instead of re-rendering the whole tree on every change. Net effect: fewer wasted renders, simpler internals, and toast() works identically whether or not a <Toaster> is mounted yet.

Performance

  • Split the toast context so stable config and dynamic state re-render independently.
  • Memoized per-toast styles; replaced O(n) lookups with O(1) Map indexes.
  • Killed a re-render cascade where every toast re-rendered on any height change.
  • Removed redundant useSyncExternalStore wrapping in ToasterUI.

Bug fixes

  • Center position now anchors at the vertical midline and mirrors bottom stacking.
  • Bottom-center safe-area handling fixed.
  • onAutoClose no longer fires twice; areActionsEqual no longer reports false positives.
  • Numeric toast IDs (including id=0) work everywhere — timer resume, wiggle guard, stale-height cleanup.
  • Promise toast height is reset on state transition so the resolved toast doesn't inherit the loading toast's size.
  • Stale toastHeights entries are cleared when toasts are shifted out.
  • Android: absolute positioning moved outside ToastSwipeHandler so swipe gestures hit-test correctly.
  • Close button on stacked-and-expanded toasts now dismisses explicitly.
  • Typo: possiblePossitionpossiblePosition.
  • TypeScript: all errors in src and the example app resolved; type exports and toast prop spread order restored.

Tooling & infra

  • Migrated from yarn to pnpm. Workspaces, CI cache, and Netlify docs build all use pnpm now.
  • Upgraded to ESLint 10 (flat config); dropped unused lint deps.
  • Added unit tests and a CI workflow (Node 22, shared setup action).
  • Aligned and deduplicated dependency versions across workspaces.
  • Example app rewritten with Expo Router, native UI, and a settings screen for live Toaster config.

Don't miss a new sonner-native release

NewReleases is sending notifications on new releases.