npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nicojones/toast

v2.2.4

Published

A simple notification library for React. Fully customizable and lightweight.

Downloads

903

Readme

React Badge Vitest Badge

🌟 Features

  • [x] 🪴 Ultra-lightweight core.
  • [x] 🦾 Fully accessible (ARIA-friendly).
  • [x] 🌓 Built-in light, dark, & system themes.
  • [x] 🕶️ Pause dismissal on hover.
  • [x] 🌍 Customizable toast position.
  • [x] 🪞 Respects user reduced-motion settings.
  • [x] 🦄 100% TypeScript.
  • [x] 🧩 Can run inside Shadow Root (manually import styles).
  • [x] 🎛️ Fully customizable—disable all styles if desired.
  • [x] 🔄 Replace/update content of already open toasts by ID.
  • [x] 🚦 Close toasts programmatically.

🚀 Getting Started

[!IMPORTANT] This library requires React v18 or higher.

  1. Install the library:
# Using npm:
npm install @nicojones/toast

# Using pnpm:
pnpm add @nicojones/toast

# Using yarn:
yarn install @nicojones/toast
  1. Add the toast provider:
// 📃 root.tsx

import { Toaster } from "@nicojones/toast";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
    <Toaster />
  </React.StrictMode>,
);
  1. Usage:
// 📃 index.tsx

import { toast } from "@nicojones/toast";

export default function Index() {
  return (
    <>
      <button
        onClick={() =>
          toast.success({
            text: "Success!",
            description: "Your action was completed successfully",
          })
        }
      >
        Show Toast
      </button>
    </>
  );
}

📖 Documentation

Toast Variants

Show a toast with a specific variant:

import { toast } from "@nicojones/toast";

// Default toast
toast.default({
  text: "Hello ✨",
});

// Success toast
toast.success({
  text: "Success!",
  description: "Operation completed successfully",
});

// Error toast
toast.error({
  text: "Error!",
  description: "Something went wrong",
});

// Warning toast
toast.warning({
  text: "Warning!",
  description: "Please check your input",
});

// Info toast
toast.info({
  text: "Info",
  description: "Here's some information",
});

Action Buttons

Show a button and execute a custom function when clicked. The default text for the button is Action:

toast.default({
  text: "A toast with action button",
  action: {
    content: "Action", // Button label
    onClick: () => {
      // Do something
      console.log("Action clicked!");
    },
  },
});

Replacing Toasts by ID

You can replace an existing toast by providing the same id. This is useful for updating progress or preventing duplicate toasts:

// First toast with ID
toast.info({
  id: "update-toast",
  text: "Processing...",
});

// Later, replace it with the same ID
toast.success({
  id: "update-toast",
  text: "Completed!",
});

Toast Loading

Show a toast with loading state that automatically updates after a promise resolves or fails:

const somePromise = (): Promise<Foo> => { ... }

toast.loading<Foo>({
  // Initial message:
  text: "Loading",
  options: {
    promise: somePromise(),
    success: "Ready",
    error: "Error",
    // Close toast automatically (the duration depends by delayDuration property):
    autoDismiss: true,
    // Optional:
    onSuccess: (data) => {
      // `data is of type Foo`
      console.log("Success", data);
    },
    // Optional:
    onError: (error, id) => {
      console.log("Error", error);
      // Replace the toast and use the error.message
      toast.error({text: error.message, id });
    },
  },
});

Example with async function:

const fetchData = async () => {
  const response = await fetch("/api/data");
  return response.json();
};

toast.loading({
  text: "Fetching data",
  options: {
    promise: fetchData(),
    success: "Data loaded",
    error: "Failed to load data",
    autoDismiss: true,
    onSuccess: (data) => {
      console.log("Received:", data);
      // Replace the toast and use received data
      toast.success({ text: data.message, id });
    },
  },
});

Closing Toasts

Close a toast programmatically using toast.close():

import { toast } from "@nicojones/toast";

// Show a toast and store its ID
const toastData = toast.info({
  text: "This will be closed",
});

// Close it later
toast.close(toastData.id);

Or close by the ID you provided:

toast.info({
  id: "my-toast",
  text: "This toast has an ID",
});

// Close it using the ID
toast.close("my-toast");

Custom Icon

You can use a custom icon for a toast using the icon property and passing any valid JSX.Element.

toast.default({
  text: "Party popper!",
  icon: <FontAwesomeIcon width={18} height={18} icon={faPoo} />,
});

Custom Attributes

You can pass custom HTML attributes to the toast:

toast.default({
  text: "Custom toast",
  attrs: {
    "aria-customized": "yes",
    "data-testid": "my-test-id",
    style: {
      color: "pink",
    },
  },
});

🍞 Toaster Component

The <Toaster /> component is used to show toasts in your application. It accepts several props for customization.

Position

By default, the position is bottom-right. You can customize the position:

import { Toaster } from "@nicojones/toast";

<Toaster position="top-left" />
<Toaster position="top-right" />
<Toaster position="top-center" />
<Toaster position="bottom-left" />
<Toaster position="bottom-right" /> {/* default */}
<Toaster position="bottom-center" />

Theme

You can set the theme of the toasts using the theme prop:

<Toaster theme="light" />
<Toaster theme="dark" />
<Toaster theme="system" /> {/* default */}

Max Toasts

By default, the maximum number of toasts is set to 4. You can change this value:

<Toaster maxToasts={8} />

Toast Options

You can customize all toasts globally using the toastOptions prop:

<Toaster
  toastOptions={{
    font: "font-sans",
    defaultActionContent: "Close me",
    defaultCloseContent: "Close",
    animationOnClose: "slide", // or "swipe"
  }}
/>

Custom Icons

Replace the default icons for all toasts:

import { Info, CircleX, CircleAlert, CircleCheck, Loader } from "lucide-react";

<Toaster
  toastOptions={{
    icons: {
      info: <Info className="dark:text-blue-500" />,
      error: <CircleX className="text-red-500" />,
      warning: <CircleAlert className="text-yellow-500" />,
      success: <CircleCheck className="text-green-500" />,
      loading: <Loader className="animate-spin text-gray-500" />,
    },
  }}
/>;

Custom Styles

Extend the default styles using the classNames property:

<Toaster
  toastOptions={{
    classNames: {
      toast: "bg-zinc-100 dark:bg-zinc-900",
      container: "rounded-lg",
      icon: "text-blue-500",
      content: "text-sm",
      actions: {
        container: "flex gap-2",
        closeBtn: "text-gray-500",
        actionBtn: "text-blue-600",
      },
    },
  }}
/>

Headless Mode

Disable all default styles using headless property. It works together with classNames:

<Toaster
  toastOptions={{
    headless: true,
    classNames: {
      toast: "bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4",
      // ... other custom styles
    },
  }}
/>

🔧 Framework Guides

Next.js

  1. Add the Toaster to your layout.tsx:
// 📃 app/layout.tsx

import { Toaster } from "@nicojones/toast";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <Toaster />
      </body>
    </html>
  );
}
  1. Use the toast function in client components:
"use client";

import { toast } from "@nicojones/toast";

export default function MyComponent() {
  return (
    <button
      onClick={() =>
        toast.success({
          text: "Ready 🎉",
        })
      }
    >
      Click me!
    </button>
  );
}
  1. (Optional) Add the styles if needed:
// 📄 app/layout.tsx

import "@nicojones/toast/dist/styles.css";

Astro

  1. Add the Toaster to your layout with client:load:
// 📄 layouts/Layout.astro

---
import { Toaster } from "@nicojones/toast";
---

<!doctype html>
<html lang="en">
  <body>
    <slot />
    <Toaster client:load />
  </body>
</html>
  1. Create a component to trigger toasts:
// 📄 components/showToast.tsx

import { toast } from "@nicojones/toast";

const ShowToast = () => {
  const handleClick = () => {
    toast.default({
      text: "Hello from Astro!",
    });
  };

  return (
    <button type="button" onClick={handleClick}>
      Show Toast
    </button>
  );
};

export default ShowToast;
  1. Use the component in your pages:
// 📄 pages/index.astro

---
import Layout from "../layouts/Layout.astro";
import ShowToast from "../components/showToast";
---

<Layout title="Welcome">
  <main>
    <ShowToast client:load />
  </main>
</Layout>

📚 API Reference

toast.{variant}()

The toast function accepts the following options:

| Property | Description | Type | Required | | --------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -------- | | text | Notification title | string | ✅ | | description | Toast's description | string | - | | icon | Icon to display in the toast | ReactNode | - | | delayDuration | Duration before the toast disappears | number (default: 4000) | - | | variant | Variant of the toast | Variant: info, success, warning, error or loading | - | | theme | Theme of the toast | Theme (default: system): light, dark or system | - | | action | Show an Action button and execute a function | { content?: string \| ReactNode, onClick: () => void \| Promise<void> } | - | | id | Set a unique id to replace an existing toast or ensure there are no duplicates | string or number | - | | attrs | Custom HTML attributes | HTMLProps<HTMLDivElement> | - |

toast.loading()

The toast.loading function accepts the same options as above, plus:

| Property | Description | Type | Required | | --------- | ------------------------ | ------------- | -------- | | options | Loading-specific options | LoadingType | - |

LoadingType

| Property | Description | Type | Required | | ------------- | ------------------------------------------ | ------------------------------------- | -------- | | promise | Promise or function that returns a promise | Promise<T> or () => Promise<T> | ✅ | | success | Success message | string | ✅ | | error | Error message | string | ✅ | | autoDismiss | Close toast automatically after promise | boolean | ✅ | | onSuccess | Callback when promise resolves | (data: T, id: ToastId) => void | - | | onError | Callback when promise rejects | (error: Error, id: ToastId) => void | - |

toast.close()

Close a toast by its ID:

toast.close(id: ToastId): void

<Toaster />

The <Toaster /> component accepts the following options:

| Property | Description | Type | Required | | -------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------- | | theme | Theme of all toasts | Theme (default: system): 'light', 'dark', or 'system' | - | | maxToasts | Maximum number of toasts to display | number (default: 4) | - | | toastIcons | Replace the default icons with custom icons | Record<Variant, ReactNode> | - | | position | Position of the toaster on the screen | Position (default: bottom-right): 'top-left', 'top-right', 'top-center', 'bottom-left', 'bottom-right' or 'bottom-center' | - | | toastOptions | Options to customize all toasts | ToastOptions | - |

ToastOptions

| Property | Description | Type | Required | | ---------------------- | --------------------------------------------------------------- | ---------------------------- | -------- | | font | Font for all toasts | string | - | | icons | Icons for all toasts | Record<Variant, ReactNode> | - | | defaultActionContent | Default content for the action button | string or ReactNode | - | | defaultCloseContent | Default content for the close button | string or ReactNode | - | | headless | Disable all default styles. It works together with classNames | boolean | - | | animationOnClose | Animation when closing toast | 'slide' or 'swipe' | - | | classNames | Custom styles for all toasts | ToastClassnames | - |

ToastClassnames

| Property | Description | Type | Required | | ----------- | ------------------------------------- | ------------------------------ | -------- | | toast | Global toast style | string | - | | container | Toast container styles | string | - | | icon | Styles for the main icon of the toast | string | - | | content | Styles for title and description | string | - | | actions | Styles for the buttons | ToastActionsCustomClassnames | - |

ToastActionsCustomClassnames

| Property | Description | Type | Required | | ----------- | ------------------------ | -------- | -------- | | container | Action buttons container | string | - | | closeBtn | Close button styles | string | - | | actionBtn | Action button styles | string | - |

🤝 Contributing

  • Library: React 19 with tsup + Lightning CSS + Vitest for testing.
  1. Fork the repository.

  2. Install dependencies:

# Install pnpm globally if you don't have it:
npm install -g pnpm

# and install dependencies:
pnpm install
  1. Commands:
# Run packages:
pnpm dev

# Build the docs & library:
pnpm build

# Test the library:
pnpm test

📃 License

MIT License - 2026.