| name | goey-toast |
| description | Install and use goey-toast — a gooey, morphing React toast component built on Sonner with Framer Motion. Use when adding toast/notification UI to a React app (success/error/warning/info/promise toasts), or when the user mentions goey-toast / gooey toast. |
| license | MIT |
goey-toast
A gooey, morphing React toast component built on Sonner with Framer Motion
animations (pill → blob → pill). Use this skill to install the package and write
correct usage code in any React project.
When to use
- Adding toast / notification UI to a React app (React >= 18).
- The user mentions "goey-toast", "gooey toast", or wants animated/morphing toasts.
- Replacing raw
sonner toasts with the gooey variant.
Install
npm install goey-toast react react-dom framer-motion
Peer deps (must exist in the host app):
| Package | Version |
|---|
| react | >= 18.0.0 |
| react-dom | >= 18.0.0 |
| framer-motion | >= 10.0.0 |
shadcn/ui projects
npx shadcn@latest add https://goey-toast.vercel.app/r/goey-toaster.json
Installs a wrapper at components/ui/goey-toaster.tsx and auto-installs deps.
Two required steps to render toasts
- Mount
<GooeyToaster /> once near the app root.
- Import the stylesheet once at the entry point. Without it toasts render
unstyled.
import { GooeyToaster, gooeyToast } from 'goey-toast'
import 'goey-toast/styles.css'
function App() {
return (
<>
<GooeyToaster position="bottom-right" />
<button onClick={() => gooeyToast.success('Saved!')}>Save</button>
</>
)
}
API: gooeyToast
gooeyToast(title, options?)
gooeyToast.success(title, options?)
gooeyToast.error(title, options?)
gooeyToast.warning(title, options?)
gooeyToast.info(title, options?)
gooeyToast.promise(promise, data)
gooeyToast.update(id, options)
gooeyToast.dismiss(idOrFilter?)
Common options (2nd arg)
| Option | Type | Notes |
|---|
description | ReactNode | String or component body |
action | GooeyToastAction | { label, onClick, successLabel? } |
icon | ReactNode | Custom icon (null clears in update) |
duration | number | ms |
id | string | number | Stable id (needed for update) |
fillColor / borderColor / borderWidth | colors / px | Blob styling |
spring / bounce | boolean / number | bounce 0.05–0.8, default 0.4 |
preset | 'smooth' | 'bouncy' | 'subtle' | 'snappy' | Animation preset |
showProgress | boolean | Countdown bar |
showTimestamp | boolean | Default true |
onDismiss / onAutoClose | (id) => void | Dismiss callbacks |
<GooeyToaster /> key props
position ('top-left'|'top-center'|'top-right'|'bottom-left'|'bottom-center'|'bottom-right', default 'bottom-right'),
theme ('light'|'dark'), closeButton, showProgress, closeOnEscape,
maxQueue, queueOverflow ('drop-oldest'|'drop-newest'), dir ('ltr'|'rtl'),
spring, bounce, preset, swipeToDismiss, showTimestamp, gap, offset.
Recipes
Description + action button
gooeyToast.info('Share link ready', {
description: 'Your link has been generated.',
action: {
label: 'Copy',
onClick: () => navigator.clipboard.writeText(url),
successLabel: 'Copied!',
},
})
Promise toast
gooeyToast.promise(saveData(), {
loading: 'Saving...',
success: (data) => `Saved ${data.count} items`,
error: (e) => `Failed: ${String(e)}`,
description: { success: 'All changes synced.', error: 'Try again later.' },
action: { error: { label: 'Retry', onClick: () => retry() } },
})
Update in place
const id = gooeyToast('Uploading...', { icon: <Spinner /> })
gooeyToast.update(id, { title: 'Done', type: 'success', icon: null })
Dismiss by filter
gooeyToast.dismiss(id)
gooeyToast.dismiss({ type: 'error' })
gooeyToast.dismiss({ type: ['error','warning'] })
gooeyToast.dismiss()
Gotchas
- Forgetting
import 'goey-toast/styles.css' → unstyled toasts. Most common bug.
<GooeyToaster /> must be mounted exactly once, near the root.
update() requires the same id returned from the create call.
framer-motion is a peer dep — install it explicitly.
- Backward-compat aliases exist (
GoeyToaster, goeyToast) for v0.2.x; prefer
the double-o names (GooeyToaster, gooeyToast).
Reference