Nefe James Nefe is a frontend developer who enjoys learning new things and sharing his knowledge with others.

Top React toast libraries compared

6 min read 1862

React Toast Libraries Compared

Introduction

You may find there are times when you want to send notifications to your users based on the state of their interaction or some other variable. This is where toast notifications come in handy.

While it is possible to create a custom toast component for React, you may find that a freely available library meets your development needs. Read on to compare four of the top React toast libraries.

react-hot-toast

The creators of react-hot-toast describe it as “the best toast in town.” One thing I particularly love about this library is its design: it has one of the best-designed toasts I’ve seen.

Usage

Through the toast API, we have access to the success method. The Toaster component is responsible for rendering all toasts. This is all it takes to set up a basic toast with react-hot-toast:

import toast, { Toaster } from "react-hot-toast";
const successToast = () => toast.success("This is a success toast.");

export default function App() {
  return (
    <div>
      <button onClick={successToast}>Success toast</button>
      <Toaster />
    </div>
  );
}

Toast variants

react-hot-toast provides four toast variants: success, error, loading, and promise.

toast.success();
toast.error();
toast.loading();
toast.promise();

The promise toast is useful when you want to update a toast after some event, say, once fetching data from an API has been completed.

import toast, { Toaster } from "react-hot-toast";

const simulateFetch = () => {
  toast.promise(fetchData(), {
    loading: "Fetching data",
    success: "Data fetched successfully",
    error: "Error when fetching",
  });
};

export default function App() {  
  return (
    <div>
      <button onClick={simulateFetch}>Fetch Data</button>
      <Toaster />
    </div>
  );
} 

There may be cases where you want to create a custom toast to meet your project needs. react-hot-toast is certainly customizable enough, so you can do that. Here, we pass a function to toast that returns the custom toast:

const customToast = () =>
  toast((t) => (
    <span>
      I am a custom toast
      <button onClick={() => toast.dismiss(t.id)}>Dismiss</button>
    </span>
  ));

export default function App() {
  return (
    <div>
      <button onClick={customToast}>show custom toast</button>
      <Toaster />
    </div>
  );
}

Configuration

The second argument of the toast API is an options object, with which you can configure the behavior of each toast. We can indicate the duration of the toast, change its style, set custom icons, define its accessibility properties, and change the theme of its icon.

import { AiFillAndroid } from "react-icons/ai";

toast.error("error toast", {
  duration: 7000,

  //icon config
  iconTheme: {
    primary: "white",
    secondary: "black",
  },

  //ARIA config
  role: "status",
  ariaLive: "polite",

  //toast styles
  style: {
    background: "red",
    color: "whitesmoke",
    icon: <AiFillAndroid />,
  },
});

Features

There are several ways to dismiss toasts with React Hot Toasts. You can dismiss a single toast. If you don’t pass in a toast reference to the dismiss method, it will dismiss all toasts at once.

const successToast = toast.success('This is a successt toast');
toast.dismiss(successToast);

toast.dismiss() //this will dismiss all toasts at once 

Developer experience

Apart from having well-designed toasts, react-hot-toast has well-structured documentation. I also love how easy it is to add custom icons to each toast. This is a library that is worth checking out.

We made a custom demo for .
No really. Click here to check it out.

Notyf

Notyf is a lightweight and easy-to-use JavaScript library for creating toast notifications. It is compatible with React, Vue, and Angular.

Usage

We create a new instance of the Notyf class and use it to set up our toast. Here, we access the success method from the instance. This method takes a string containing the toast message as its only argument. We attach the successToast function to a button’s onClick event, and that’s all it takes to set up a basic toast using Notyf.

import "./styles.css";
import { Notyf } from "notyf";
import "notyf/notyf.min.css";

const notyf = new Notyf();
const successToast = () => notyf.success("This is a success toast");

export default function App() {
  return (
    <div className="App">
      <button onClick={successToast}>show success toast</button>
    </div>
  );
}

Toast variants

Unlike the other libraries in this article, Notyf comes with just two types of toasts out of the box: a success toast and an error toast. It would be awesome if the library provided additional inbuilt toast variants.

notyf.success("success toast");
notyf.error("error toast");

Configuration

The Notyf instance can take as its argument an optional object, in which we define the toast’s behavior. Here, we define the duration of the toast, the position from which we want it to appear, and whether we want the user to be able to dismiss the toast.

const notyf = new Notyf({
  duration: 1000,
  dismissiblea: true,
  position: {
    x: "right",
    y: "top",
  },
}

Features

You can dismiss a particular toast. When the dismiss method is called, successToast will be dismissed even if its duration has not elapsed. You can also dismiss all toasts that are present with the dismissAll method.

const successToast = () => notyf.success("This is a success toast");
notyf.dismiss(successToast);

notyf.dismissAll(); //dismiss all open toasts

While Notyf comes with just the success and error toasts out of the box, you can create your own custom toasts. We define and style any custom toasts in the types array.

In the snippet below, we set up a custom loading toast that will be useful when fetching data or submitting a form. To use custom toasts, we use the open method and pass it an object containing the name of the custom toast and its message.

//define custom loading toast
const notyf = new Notyf({
  types: [
    {
      type: "loading",
      background: "black",
      duration: 2000,
      dismissible: true,
    },
    //other custom toasts if any
  ],
});

//call loading toast
const showCustomToast = () => {
  notyf.open({
    type: "loading",
    message: "Fetching data...",
  });
};

Developer experience

The developer experience would be better if the library covered a loading toast that gets updated when an async event has been completed. Aside from that, Notyf is a dead-simple toast library to use. While Notyf is not packed with as many features as the other React toast libraries in this article, it still covers most common use cases.

React Toast Notifications

React Toast Notifications is a configurable, composable, toast notification system for react.

Usage

To use React Toast Notifications, wrap your app in the ToastProvider, which provides context for the Toast descendants.

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { ToastProvider } from "react-toast-notifications";

ReactDOM.render(
  <React.StrictMode>
    <ToastProvider>
      <App />
    </ToastProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

Through the useToast hook, we have access to the addToast method. Its first argument is a string containing the toast message, and the second is a configuration object. In the config object, we set the appearance of the toast to success and autoDismiss to true.

import { useToasts } from "react-toast-notifications";

export default function App() {
  const { addToast } = useToasts();
  const successToast = () => {
    addToast("This is a success toast", {
      appearance: "success",
      autoDismiss: true,
    });
  };
  return (
    <div className="App">
      <button onClick={successToast}>show success toast</button>
    </div>
  );
}

Toast variants

Four toast notifications are available in React Toast Notifications: success, error, warning, and info.

addToast("success toast", { appearance: "success"});
addToast("error toast", { appearance: "error"});
addToast("warning toast", { appearance: "warning"});
addToast("info toast", { appearance: "info"});

Configuration

We can configure toasts in React Toast Notifications by passing props to the ToastProvider.

<ToastProvider 
  placement="top-center" 
  transitionDuration={2000}
  autoDismiss="true"
 autoDismissTimeout={5000}>
  <App />
</ChakraProvider>

When configuring with the ToastProvider, the placement, transitionDuration, autoDismiss, and autoDismissTimeout are passed as props, and then inherited by the descendant toast component.

Features

We have access to the following methods from the useToast hook:

const { addToast, removeToast, removeAllToasts, updateToast } = useToast()

We already know how the addToast method works. We can remove a specific toast with removeToast and remove all open toasts with removeAllToasts. The updateToast method can be useful when we want to update a toast after an operation has been completed, say, after some data has been fetched.

Developer experience

While React Toast Notifications’ API is straightforward, it is not the simplest to work with. As far as the docs go, there’s room for improvement, particularly in showing how a user ID can be passed to a toast, and how a toast can be removed and updated. Overall, React Toast Notifications lacks extensive and clear documentation.

React-Toastify

ReactToastify is a highly customizable React toast library that allows us to add notifications to our apps with ease.

Usage

React-Toastify has a similar API to react-hot-toast. Through the toast API, we can access the different toast variants. The ToastContainer component is required for the toasts to appear.

import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

export default function App() {
  const successToast = () => toast.success("This is a success toast!");
  return (
    <div className="App">
      <button onClick={successToast}>show success toast</button>
      <ToastContainer />
    </div>
  );
}

Toast variants

React-Toastify has the most variants of any library in this article. It provides six toast variants: success, error, warn, info, dark, and a default variant.

toast.success("success toast")
toast.error("erorr toast")
toast.warn("warning toast")
toast.info("info toast")
toast.dark("dark mode toast")
toast("default toast")

Configuration

We can pass an options object to toast as a second argument. Here, we can define the behavior of the toast.

toast.dark("This is a success toast!", {
  position: toast.POSITION.BOTTOM_RIGHT,
  autoClose: 2000,
  pauseOnHover: true,
  draggable: true,
});

We can replace the default toast animation with the cssTransition method. It accepts an object wherein we define the enter and exit animations for the toast.

import "animate.css/animate.min.css";
import { ToastContainer, toast, cssTransition } from "react-toastify";

const bounce = cssTransition({
  enter: "animate__animated animate__bounceIn",
  exit: "animate__animated animate__bounceOut",
});

const customAnimationToast = () => {
  toast.dark("Hey 👋, see how easy!", {
    transition: bounce,
  });
};

export default function App() {
  return (
    <div className="App">
      <button onClick={customAnimationToast}>show bounce toast</button>
      <ToastContainer transition={bounce} />
    </div>
  );
}

Features

We can update toasts programmatically in React-Toastify. Unlike react-hot-toast, however, where we can store a reference to a toast in a variable, we have to use the useRef hook to track the toast we want to update.

import { useRef } from "react";

export default function App() {
  let toastId = useRef(null);

  const successToast = () => {
    toastId = toast("Fetching data...", { autoClose: false });
  };

  const updateToast = () => {
    toast.update(toastId, { type: toast.TYPE.INFO, autoClose: 5000 });
  }

  return (
    <div>
      <button onClick={successToast}>show success toast</button>
      <Button onClick={updateToast}>update toast</Button>
      <ToastContainer ref={toastId} />
    </div>
  );
}

Developer experience

React-Toastify has more toast variants than any other library above, and it has a lot of awesome features. As for the API, it’s fairly similar to the react-hot-toast and React Toast Notifications APIs.

Conclusion

After comparing these four React toast libraries and learning how to use them in our apps, it’s time to share an opinion on the best of the bunch. I enjoy using react-hot-toast above the rest. Aside from its well-designed toasts and straightforward API, it comes with a promise toast that makes it easy to asynchronously update toasts.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Nefe James Nefe is a frontend developer who enjoys learning new things and sharing his knowledge with others.

One Reply to “Top React toast libraries compared”

Leave a Reply