
Physics Toast is a vanilla JavaScript library that creates Apple Dynamic Island-style toast notifications with SVG-based gooey morphing effects. Inspired by React Sileo and powered by a real damped spring physics engine.
Features:
- Real spring physics engine: Animations are driven by a damped spring simulation (
F = -kx - cv), sub-stepped at ≤4 ms intervals. - SVG gooey morphing: The pill indicator and the body panel are separate SVG rectangles fused through a shared
feGaussianBlur+feColorMatrixfilter. - 6 toast types:
success,error,warning,info,promise(async loading state), andaction(with a clickable button). - 6 screen positions:
top-left,top-center,top-right,bottom-left,bottom-center, andbottom-right. - Interrupt-safe replace behavior: When a new toast targets an occupied position, the spring picks up from the current velocity and crossfades in-place. No flash, no reset, and no stacking.
- Auto expand/collapse: The description panel opens and closes on a configurable timer.
- Swipe to dismiss: Pointer drag exceeding 30 px dismisses the active toast.
- CSS custom properties: All colors, dimensions, and transition durations are exposed as
:rootvariables and are fully overridable.
See It In Action:
How To Use It:
1. Download and import the Physics Toast library’s script & stylesheet in the document.
<link rel="stylesheet" href="physics-toast.min.css"> <script src="physics-toast.min.js"></script>
2. On load, the SDK auto-injects six viewport container elements (one per position) and a single shared SVG <filter> element into <body>. You do not need to add any extra HTML.
3. Create basic toast notifications.
// Show a success toast with a title and optional description
toast.success('Success', 'Your success message.')
// Show an error toast
toast.error('Error', 'Your error message.')
// Warning and info variants follow the same signature
toast.warning('Warning', 'Your warning message.')
toast.info('Info', 'Your info message.')4. Create advanced promise toast notifications (Async Operations).
The
promisetype shows a loading spinner immediately and transitions tosuccessorerroronce the provided function resolves or rejects.
toast.promise(
'Uploading...', // Title shown during loading
() => fetch('/api/upload', { // Any function that returns a Promise
method: 'POST',
body: formData
}),
{
success: { title: 'Done', description: 'File uploaded.' },
error: { title: 'Failed', description: 'File Upload Failed' }
}
)5. Create an Action toast notification with a clickable button.
toast.action( 'Action Toast', 'Your Toast Message Here', 'Check it Out', () => openMessage() )
6. Set the duration and position of the toast notifications.
duration(number): Time in milliseconds before the toast auto-dismisses. Defaults to4000. Set to0to require manual dismissal.position(string): Screen position for the toast. Accepted values:top-left,top-center,top-right,bottom-left,bottom-center,bottom-right. Defaults totop-center.
toast.success('Success Toast', 'Success Toast Message', {
duration: 5000,
position: 'top-right'
})// OR apply new defaults that affect all subsequent toast calls toast.defaults.duration = 6000 toast.defaults.position = 'bottom-right'
7. Dismiss or clear toast notifications.
// Dismiss a single toast by its ID toast.dismiss(id) // Dismiss all active toasts immediately toast.clear()
8. Create your own themes with CSS Custom Properties:
:root {
--sileo-spring-easing: linear(0, 0.002 0.6%, 0.007 1.2%, 0.015 1.8%, 0.026 2.4%, 0.041 3.1%,
0.06 3.8%, 0.108 5.3%, 0.157 6.6%, 0.214 8%, 0.467 13.7%,
0.577 16.3%, 0.631 17.7%, 0.682 19.1%, 0.73 20.5%, 0.771 21.8%,
0.808 23.1%, 0.844 24.5%, 0.874 25.8%, 0.903 27.2%, 0.928 28.6%,
0.952 30.1%, 0.972 31.6%, 0.988 33.1%, 1.01 35.7%, 1.025 38.5%,
1.034 41.6%, 1.038 45%, 1.035 50.1%, 1.012 64.2%, 1.003 73%,
0.999 83.7%, 1);
--sileo-duration: 550ms;
--sileo-height: 40px;
--sileo-width: 350px;
--sileo-state-success: oklch(0.723 0.219 142.136);
--sileo-state-loading: oklch(0.556 0 0);
--sileo-state-error: oklch(0.637 0.237 25.331);
--sileo-state-warning: oklch(0.795 0.184 86.047);
--sileo-state-info: oklch(0.685 0.169 237.323);
--sileo-state-action: oklch(0.623 0.214 259.815);
}Alternatives:
- Sonner: The most popular modern toast library. Sonner is React-specific and ships with Framer Motion transitions.
- Toastify JS: A lightweight (~2 KB) vanilla JS option focused on simplicity.
- Notyf: A clean, accessible toast library with TypeScript support and a simple API.
- 10 Best Toast Notification JavaScript Libraries
FAQs:
Q: Can I use Physics Toast in a React or Vue project?
A: Yes. Include the script and stylesheet via <link> and <script> tags in your index.html, or import the files at the application entry point. Call toast.success() from any component. The library operates on the global window.toast object, so it stays outside the component tree entirely. One caveat: you lose React’s rendering lifecycle guarantees for the toast DOM, so avoid trying to manage toast elements through React refs.
Q: How do I prevent a toast from auto-dismissing?
A: Set duration: 0 in the options object. The toast will stay on screen until toast.dismiss(id) or toast.clear() is called explicitly.
Q: Does Physics Toast support right-to-left (RTL) layouts?
A: Not out of the box. The pill position is calculated using left-offset logic, and the description panel is left-aligned. For RTL projects, you would need to override the relevant CSS custom properties and adjust the x attribute calculations in the source.
Q: Can I show more than one toast at a time?
A: Yes, across different positions. Each of the six positions holds one active toast. If you fire toast.success() to top-center and toast.error() to bottom-right simultaneously, both display independently. Firing two toasts to the same position causes the second to replace the first with a physics-continuous crossfade.







