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

react-tostack

v0.1.1

Published

iOS Dynamic Island style toasts for React. Spring physics, stacking, glass surfaces, light and dark themes. Written in TypeScript.

Readme

react-tostack

Toasts made of light and glass. A Dynamic Island that morphs between messages on spring physics, closes with one tap, and expands for details.

Styled with Lume, a light-first design language: frosted glass that blurs the page behind it, a specular edge on top, one warm lamp accent, and motion on springs.

  • Dynamic Island mode: one toast attached to the screen edge, morphing in place
  • Stacked mode for any of the 6 positions
  • Spring physics running outside React (no re-renders while animating)
  • Close button by default, optional swipe to dismiss, tap to expand, hover to pause, Esc to close
  • Lume glass material (or material="solid"), light, dark and system themes, animated glow edge and rich colors
  • react-hot-toast compatible API
  • Written in TypeScript, works the same from JavaScript (ESM + CommonJS)
  • No dependencies besides React 18+

Install

npm i react-tostack

Usage

import { Toaster, toast } from 'react-tostack';

export default function App() {
  return (
    <>
      <Toaster />
      <button onClick={() => toast.success('Saved to Photos')}>Save</button>
    </>
  );
}

Styles are injected automatically. Put <Toaster /> once, near the root.

API

toast('Silent mode on', { icon: '🔕' });
toast.success('Saved');
toast.error('Upload failed');
toast.warning('Battery at 10%', { accessory: '10%' });
toast.info('Focus is on');
toast.loading('Syncing…');
toast.custom(<NowPlaying />);

// Update in place: the toast morphs to the new content
const id = toast.loading('Uploading…');
toast.success('Uploaded', { id });

// Promise
toast.promise(save(), {
  loading: 'Saving…',
  success: (data) => `Saved ${data.name}`,
  error: 'Could not save',
});

toast.dismiss(id); // animate out (no id: all)
toast.remove(id);  // remove instantly

Expandable toasts

Tap a toast that has a description or actions to expand it. In island mode you can also pull it down.

toast('New message', {
  icon: '✉️',
  accessory: 'now',
  description: 'Are we still on for 7?',
  actions: [
    { label: 'Reply', primary: true, onClick: (t) => openChat() },
    { label: 'Later' },
  ],
});

An action closes the toast unless its onClick returns false.

Toast options

| Option | Type | Default | | --- | --- | --- | | id | string | auto | | duration | number (ms) | success 2500, loading Infinity, others 4000 | | position | ToastPosition | from <Toaster> | | icon | ReactNode (null hides it) | by type | | iconTheme | { primary, secondary } | by type | | description | ReactNode | — | | accessory | ReactNode | — | | actions | ToastAction[] | — | | expanded | boolean | false | | accent | CSS color | by type | | glow | boolean | false | | closeButton | boolean | true | | richColors | boolean | false | | dismissible | boolean (swipe to close) | false | | className, style | | — | | ariaProps | { role, 'aria-live' } | status / alert for errors | | onClick, onDismiss, onAutoClose | (toast) => void | — |

style.background sets the toast surface color.

<Toaster /> props

| Prop | Type | Default | | --- | --- | --- | | position | top-left top-center top-right bottom-left bottom-center bottom-right | top-center | | theme | light dark system | system | | island | boolean \| 'auto' | auto (on for top-center) | | reverseOrder | boolean | false | | gutter | number | 8 | | offset | number | 16 | | toastOptions | default options, plus per type: { success: {…}, error: {…} } | — | | glow | boolean | false | | closeButton | boolean | true | | richColors | boolean | false | | material | glass solid | glass | | minWidth | number \| string | 300 | | maxWidth | number \| string | 380 | | visibleToasts | number | 3 | | maxQueue | number | 3 | | spring | { stiffness, damping } | { 260, 26 } | | container | HTMLElement | document.body | | containerStyle, containerClassName | | — |

Island mode works with top-center and bottom-center.

Stacking

Each position shows up to visibleToasts (3) at once: the newest in front, the others tucked behind it as thin layers. Hover the stack (or tap it on touch) to fan it out into a list. Only the front toast counts down, so a stack plays out one by one; toasts beyond the visible ones wait in a queue. When more than maxQueue (3) are waiting, the oldest are dropped, except errors and loading toasts.

Theming

Every color is a CSS variable on .tostack-root, so you can override them:

.tostack-root[data-theme='dark'] {
  --tostack-bg: rgba(0, 0, 0, 0.6);
  --tostack-lume: #ffb547;
  --tostack-green: #30d158;
}

Available: --tostack-bg (glass tint), --tostack-solid (solid surface), --tostack-blur, --tostack-fg, --tostack-fg2, --tostack-spec (top edge light), --tostack-hairline, --tostack-btn, --tostack-drop, --tostack-lume and --tostack-on-lume (accent), and the colors green, mint, teal, blue, indigo, pink, red, orange, yellow.

Glass needs something behind it to bend. Over video or busy images, material="solid" keeps text readable.

Headless

useToasts() returns the live toast list if you want to render your own UI.

Demo

npm install
npm run build
npx serve demo

Testing

demo/audit.js is a browser test suite (37 checks: rendering, roles, timers, update by id, stacking and queue limits, Escape, close button, actions, promises, hover, every position, widths, theme). Serve the demo, open it, then run in the console:

const s = document.createElement('script'); s.src = './audit.js'; document.body.append(s);
// when loaded
await runAudit(); // { passed, failed, results }

Keep the page visible while it runs: hidden tabs slow animation frames down.

License

MIT