<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter Anyawantana</title>
    <description>The latest articles on DEV Community by Peter Anyawantana (@ahlgren1234).</description>
    <link>https://dev.to/ahlgren1234</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F571423%2F0f23d0b1-9741-4abd-9dae-119c2dc5e302.jpeg</url>
      <title>DEV Community: Peter Anyawantana</title>
      <link>https://dev.to/ahlgren1234</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahlgren1234"/>
    <language>en</language>
    <item>
      <title>Introducing React Elegant Toasts v2.0 — A Fresh Take on Toast Notifications for React</title>
      <dc:creator>Peter Anyawantana</dc:creator>
      <pubDate>Thu, 22 Oct 2026 05:53:22 +0000</pubDate>
      <link>https://dev.to/ahlgren1234/introducing-react-elegant-toasts-v20-a-fresh-take-on-toast-notifications-for-react-26od</link>
      <guid>https://dev.to/ahlgren1234/introducing-react-elegant-toasts-v20-a-fresh-take-on-toast-notifications-for-react-26od</guid>
      <description>&lt;p&gt;&lt;strong&gt;A complete rewrite of my open-source React toast library, with a focus on developer experience, accessibility, customization, and reliability.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After a lot of development, refactoring, testing, and quite a few lessons learned along the way, I'm excited to finally release &lt;strong&gt;React Elegant Toasts v2.0&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;It's an open-source toast notification library for React 18 and 19, built with TypeScript and designed to be easy to use while handling the more complicated details behind the scenes.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://ahlgren1234.github.io/react-elegant-toasts/" rel="noopener noreferrer"&gt;Try the live demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://github.com/ahlgren1234/react-elegant-toasts" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-elegant-toasts" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why another React toast library?
&lt;/h2&gt;

&lt;p&gt;That's a fair question.&lt;/p&gt;

&lt;p&gt;There are already some excellent toast notification libraries in the React ecosystem. I'm not going to pretend otherwise.&lt;/p&gt;

&lt;p&gt;For me, this project started with a simple idea: I wanted to build something that looked good, felt natural to use, and offered a pleasant developer experience.&lt;/p&gt;

&lt;p&gt;But as the project grew, I became increasingly interested in everything happening behind the visible notification.&lt;/p&gt;

&lt;p&gt;How should timers behave when the browser tab becomes inactive?&lt;/p&gt;

&lt;p&gt;What happens when a user interacts with a toast using the keyboard?&lt;/p&gt;

&lt;p&gt;How should notifications be announced to screen readers?&lt;/p&gt;

&lt;p&gt;How do you handle multiple toast queues without losing notifications?&lt;/p&gt;

&lt;p&gt;And how do you make all of this work consistently across different browsers?&lt;/p&gt;

&lt;p&gt;Those questions eventually turned a relatively small component project into something much more interesting.&lt;/p&gt;

&lt;p&gt;With v2.0, I decided to take what I'd learned and rebuild the library around a more deliberate architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;One of my main goals was to keep the public API simple.&lt;/p&gt;

&lt;p&gt;Install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-elegant-toasts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the stylesheet, render a single &lt;code&gt;Toaster&lt;/code&gt; component, and start showing notifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-elegant-toasts/styles.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Toaster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-elegant-toasts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Changes saved!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Save changes
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Toaster&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;The library handles rendering, positioning, dismissal, timers, stacking, and animations.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;toast&lt;/code&gt; API also works outside React components, so you don't need to pass notification functions through your component tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different types of notifications
&lt;/h2&gt;

&lt;p&gt;React Elegant Toasts supports several built-in toast types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a default notification&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Profile updated successfully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something went wrong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your session is about to expire&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A new update is available&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Uploading your files...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also add descriptions, actions, custom durations, and different positions.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message archived&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You can find it in your Archive folder.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bottom-center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Undo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;restoreMessage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are six available positions, and each position maintains its own stack and queue.&lt;/p&gt;

&lt;p&gt;That last part is important. If more notifications arrive than can be displayed, the additional notifications wait for their turn rather than simply disappearing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Promise-based notifications
&lt;/h2&gt;

&lt;p&gt;One feature I particularly like is promise handling.&lt;/p&gt;

&lt;p&gt;Imagine submitting a form or saving something to an API.&lt;/p&gt;

&lt;p&gt;Instead of manually managing loading, success, and error notifications, you can use &lt;code&gt;toast.promise&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;saveProject&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Saving project...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Saved &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something went wrong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The notification starts in a loading state and updates when the promise resolves or rejects.&lt;/p&gt;

&lt;p&gt;It's a small feature, but one that makes everyday development a little nicer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customization without fighting the library
&lt;/h2&gt;

&lt;p&gt;I wanted customization to be straightforward.&lt;/p&gt;

&lt;p&gt;React Elegant Toasts includes light, dark, and system themes, with CSS custom properties for styling.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Toaster&lt;/span&gt;
  &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bottom-right"&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt;
  &lt;span class="na"&gt;maxVisible&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;progress&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-toaster"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.my-toaster&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--ret-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--ret-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also create custom toasts with your own React markup, while the library continues to manage positioning, timers, and dismissal.&lt;/p&gt;

&lt;p&gt;My goal was to provide sensible defaults without making developers feel locked into one visual style.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility was a major focus
&lt;/h2&gt;

&lt;p&gt;One of the areas that received a lot of attention during the rewrite was accessibility.&lt;/p&gt;

&lt;p&gt;Toast notifications seem simple, but they introduce some surprisingly difficult questions.&lt;/p&gt;

&lt;p&gt;A notification shouldn't unexpectedly steal keyboard focus. Users need enough time to read or interact with it. Important messages need to be communicated to assistive technologies.&lt;/p&gt;

&lt;p&gt;In v2.0, I worked on features including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live regions for notification announcements, with assertive announcements for errors.&lt;/li&gt;
&lt;li&gt;Keyboard navigation, including an Alt+T shortcut to reach notifications.&lt;/li&gt;
&lt;li&gt;Pausing dismissal timers during hover, keyboard focus, and page inactivity.&lt;/li&gt;
&lt;li&gt;Support for reduced-motion preferences.&lt;/li&gt;
&lt;li&gt;Customizable labels for assistive technology.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accessibility is an ongoing process, not a checkbox.&lt;/p&gt;

&lt;p&gt;The library has automated accessibility coverage, but I also want to be transparent: real screen-reader testing is still an area where more validation is needed. I'm not claiming conformance to a particular accessibility standard.&lt;/p&gt;

&lt;p&gt;If accessibility is something you work with, I'd genuinely appreciate feedback.&lt;/p&gt;

&lt;p&gt;You can read more in the &lt;a href="https://github.com/ahlgren1234/react-elegant-toasts/blob/main/docs/ACCESSIBILITY.md" rel="noopener noreferrer"&gt;accessibility documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A different architecture under the hood
&lt;/h2&gt;

&lt;p&gt;The biggest change in v2 isn't necessarily visible in the notifications themselves.&lt;/p&gt;

&lt;p&gt;It's the architecture.&lt;/p&gt;

&lt;p&gt;Instead of making React responsible for everything, the library uses an external store to manage toast state, queues, timers, and lifecycle behavior.&lt;/p&gt;

&lt;p&gt;The React layer is responsible for subscribing to that state and rendering the notifications.&lt;/p&gt;

&lt;p&gt;That separation made it easier to reason about important behaviors independently of the UI.&lt;/p&gt;

&lt;p&gt;It also helped make the library more testable.&lt;/p&gt;

&lt;p&gt;The public API stays intentionally small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Toaster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-elegant-toasts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the package has &lt;strong&gt;zero runtime dependencies&lt;/strong&gt;, with React and React DOM declared as peer dependencies.&lt;/p&gt;

&lt;p&gt;Version 2 is ESM-only and includes TypeScript declarations.&lt;/p&gt;

&lt;p&gt;It also supports server rendering and the Next.js App Router, including a client boundary for the toast functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing across browsers
&lt;/h2&gt;

&lt;p&gt;Another big part of the v2 development process was testing.&lt;/p&gt;

&lt;p&gt;I didn't want to rely entirely on component tests running in a simulated DOM.&lt;/p&gt;

&lt;p&gt;Some behaviors, particularly animations, gestures, focus handling, and CSS transitions, need to be tested in real browser engines.&lt;/p&gt;

&lt;p&gt;The project uses Playwright to test against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chromium&lt;/li&gt;
&lt;li&gt;Firefox&lt;/li&gt;
&lt;li&gt;WebKit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alongside the browser tests, there are unit, component, TypeScript, and accessibility-oriented tests.&lt;/p&gt;

&lt;p&gt;And I learned an interesting lesson along the way: sometimes a failing animation test isn't caused by a broken animation.&lt;/p&gt;

&lt;p&gt;We ran into a WebKit issue where animation frames weren't always delivered frequently enough for a test to observe intermediate positions. The test could fail even though the transition itself was behaving correctly.&lt;/p&gt;

&lt;p&gt;Fixing that required looking more closely at transition evidence rather than assuming every animation would produce conveniently timed frames.&lt;/p&gt;

&lt;p&gt;It's the kind of detail you rarely think about when you first decide to build a toast component!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's different about v2.0?
&lt;/h2&gt;

&lt;p&gt;Version 2.0 is a complete rewrite rather than a small update to the original implementation.&lt;/p&gt;

&lt;p&gt;Some of the highlights include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A redesigned public API.&lt;/li&gt;
&lt;li&gt;An external store for notification state and lifecycle management.&lt;/li&gt;
&lt;li&gt;Independent notification queues for all six positions.&lt;/li&gt;
&lt;li&gt;Custom toasts and promise notifications.&lt;/li&gt;
&lt;li&gt;More deliberate timer and pause behavior.&lt;/li&gt;
&lt;li&gt;Improved accessibility-related functionality.&lt;/li&gt;
&lt;li&gt;CSS-based themes and customization.&lt;/li&gt;
&lt;li&gt;Better browser and package-level testing.&lt;/li&gt;
&lt;li&gt;Support for React 18 and 19.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using an older 0.x version, please note that v2 introduces breaking changes.&lt;/p&gt;

&lt;p&gt;There's a &lt;a href="https://github.com/ahlgren1234/react-elegant-toasts/blob/main/docs/MIGRATION.md" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt; to help with the transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Releasing v2.0 feels like a big milestone, but I don't consider the project finished.&lt;/p&gt;

&lt;p&gt;I'd like to keep improving the library based on real-world use, bug reports, accessibility feedback, and ideas from other developers.&lt;/p&gt;

&lt;p&gt;I've also added contribution guidelines, issue templates, and GitHub Discussions to make it easier for people to get involved.&lt;/p&gt;

&lt;p&gt;The project is open source under the MIT license, and contributions are welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it a try!
&lt;/h2&gt;

&lt;p&gt;If you're building something with React and need toast notifications, I'd love for you to give React Elegant Toasts a try.&lt;/p&gt;

&lt;p&gt;The easiest way to see what it can do is to explore the live demo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://ahlgren1234.github.io/react-elegant-toasts/" rel="noopener noreferrer"&gt;Try React Elegant Toasts v2.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also find it here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/ahlgren1234/react-elegant-toasts" rel="noopener noreferrer"&gt;https://github.com/ahlgren1234/react-elegant-toasts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/react-elegant-toasts" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-elegant-toasts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discussions:&lt;/strong&gt; &lt;a href="https://github.com/ahlgren1234/react-elegant-toasts/discussions" rel="noopener noreferrer"&gt;https://github.com/ahlgren1234/react-elegant-toasts/discussions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you find it useful, consider giving the repository a star on GitHub. ⭐&lt;/p&gt;

&lt;p&gt;Most importantly, I'd love to hear what you think.&lt;/p&gt;

&lt;p&gt;What features do you consider essential in a React toast notification library?&lt;/p&gt;

&lt;p&gt;Are there any accessibility or usability details you'd like to see handled differently?&lt;/p&gt;

&lt;p&gt;Thanks for reading, and happy coding!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Peter Anyawantana&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;react&lt;/code&gt; &lt;code&gt;typescript&lt;/code&gt; &lt;code&gt;opensource&lt;/code&gt; &lt;code&gt;webdev&lt;/code&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>showdev</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
