
chyrp is a Vanilla JavaScript toast notification library that enables a notification to change from a loading message to a completion alert in place and supports action buttons for user responses.
Features
- Info, warning, error, and loading notification styles.
- Automatic stacking with an overflow counter for additional messages.
- 6 position options and bottom-centered placement on small screens.
- Timed dismissal with pause on hover or keyboard focus.
- Pointer-based swipe dismissal and click-to-dismiss behavior.
- Configurable suppression of duplicate notifications.
- Promise tracking with loading, completion, and error states.
- Built-in sound presets and custom audio options.
- Automatic light and dark colors with CSS variable overrides.
- Reduced-motion preferences and TypeScript definitions.
How To Use It
Basic Usage
Place the stylesheet in the document head and the script at the end of the body. chyrp needs document.body to exist when it creates a notification.
<!-- In <head> -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chyrp/dist/style.css">
<!-- Before </body> -->
<script src="https://unpkg.com/chyrp/dist/index.iife.js"></script>
<script>
Chyrp.chyrp.info('Your settings were saved.');
</script>
Or install the package and import the required CSS once in your app entry file.
npm install chyrp
import { chyrp } from 'chyrp';
import 'chyrp/style.css';
chyrp.info('Your settings were saved.');
chyrp.warning('Storage is running low.');
chyrp.error('Unable to upload the file.');
Notifications with Actions
Action buttons can handle an Undo request or another explicit operation. The example expects an application-defined restoreFile() function. The toast closes after a button click unless its onClick handler returns false.
chyrp does not wait for a promise returned from this handler, so use return false and dismiss or update the toast yourself after asynchronous work.
chyrp({
title: 'File deleted',
body: 'report.pdf was moved to the trash.',
persistent: true,
actions: [
{
label: 'Undo',
style: 'primary',
onClick: () => restoreFile()
},
{ label: 'Dismiss' }
]
});
Track an Asynchronous Task
Pass an existing promise to chyrp.promise() to show loading feedback and update the notification after resolution or rejection.
The example expects an application-defined saveSettings() function that returns a promise. The success handler receives the resolved value, and error receives the rejection reason.
chyrp.promise(saveSettings(), {
loading: 'Saving settings...',
success: () => 'Settings saved.',
error: (error) => ({
title: 'Save failed',
body: error instanceof Error ? error.message : String(error)
})
});
A loading toast displays a spinner by default. A positive max changes that indicator to a progress donut.
const progressToast = chyrp.loading('Preparing your export...', {
max: 100,
value: 0
});
progressToast.update({ value: 65, body: 'Exporting: 65%' });
progressToast.update({
style: 'info',
body: 'Your export is ready.',
timeout: 2500
});
Configure Position, Timing, and Sound
Sound is enabled by default. configure() can change the global position, hover behavior, sound, and replay settings.
import { chyrp, configure } from 'chyrp';
configure({
position: 'bottom-right',
pauseOnHover: true,
sound: false,
resound: false
});
chyrp.info('Preferences updated.', {
position: 'top-center',
timeout: 6000,
sound: 'success'
});
Update and Dismiss Notifications
Each call that creates a toast returns a ToastHandle with update() and dismiss(). You can change the message, notification style, action buttons, and timer through that handle.
const statusToast = chyrp.loading('Synchronizing data...', {
sound: false
});
setTimeout(() => {
statusToast.update({
style: 'info',
body: 'Synchronization complete.',
timeout: 2500
});
}, 1200);
channel groups notifications for dismissal. dismissChannel(name) clears that group, and dismissAll() clears every active toast.
import { chyrp, dismissChannel, dismissAll } from 'chyrp';
chyrp.warning('Connection interrupted.', {
channel: 'network',
persistent: true
});
// Later, after the connection recovers:
// dismissChannel('network');
// To clear all live notifications:
// dismissAll();
API Methods
| API | Description |
|---|---|
chyrp(options) | Creates a toast from ToastOptions and returns ToastHandle. |
show(options) | Standalone equivalent of chyrp(options). |
info(body, options?) / chyrp.info(...) | Creates an info toast and returns ToastHandle. |
warning(body, options?) / chyrp.warning(...) | Creates a warning toast and returns ToastHandle. |
error(body, options?) / chyrp.error(...) | Creates an error toast and returns ToastHandle. |
loading(body, options?) / chyrp.loading(...) | Creates a loading toast and returns ToastHandle. |
promise(promise, options) / chyrp.promise(...) | Tracks a Promise<T> with PromiseOptions<T> and returns ToastHandle. |
configure(options) / chyrp.configure(...) | Updates global ToastConfig defaults. Returns void. |
dismissAll() / chyrp.dismissAll() | Dismisses every active toast. Returns void. |
dismissChannel(name) / chyrp.dismissChannel(name) | Dismisses active toasts assigned to a string channel. Returns void. |
interceptAlert() | Overrides window.alert() with an info toast and returns a function that restores native behavior. |
A ToastHandle returned by a creation method has two methods.
| Method | Description |
|---|---|
dismiss(): void | Dismisses the notification. |
update(options: ToastOptions): ToastHandle | Changes a live notification and returns the handle for chaining. |
Full Toast Options
| Option | Type, default, and behavior |
|---|---|
title | string, default ''. Bold text above the body. |
body | string, default ''. Main notification text. |
style | 'info' | 'warning' | 'error' | 'loading', default 'info'. Sets color and built-in icon. |
timeout | number, default 4000 ms for ordinary styles and 0 for loading. Set 0 to disable the timer. |
persistent | boolean, default false. Sets the initial timeout to 0. An explicit positive timeout overrides it. |
debounce | number, default 100 ms. Suppresses repeated equivalent toasts during this window. |
swipe | boolean, default true. Enables swipe dismissal when Pointer Events are available. |
pauseOnHover | boolean, default true. Pauses the timer on hover and keyboard focus when the device is not touch-primary. |
position | ToastPosition, default 'top-right'. Accepts top-left, top-center, top-right, bottom-left, bottom-center, or bottom-right. Viewports at or below 600px use bottom-center. |
channel | string, no default. Displays a channel label and groups notifications for dismissal. |
icon | string | HTMLElement | false, no default. Displays a text icon, a cloned DOM element, or no icon. |
actions | ToastAction[], no default. Buttons below the message. |
sound | SoundOption, default true. Accepts true, false, gentle, alert, success, error, an audio URL string, or ChimeNote[]. |
resound | boolean, default false. Replays sound when an update changes style. |
max | number, no default. A positive maximum enables a determinate progress donut for loading toasts. |
value | number, default 0. Current loading progress value. The donut uses value / max when max > 0. |
Global Configuration
configure(options) accepts only the global fields below. Per-toast options have priority over their corresponding global settings.
| Option | Type, default, and behavior |
|---|---|
position | ToastPosition, default 'top-right'. Default desktop anchor position. |
pauseOnHover | boolean, default true. Controls timer pausing on desktop hover. |
sound | SoundOption, default true. Default notification sound. |
resound | boolean, default false. Controls sound replay when a toast changes style. |
soundPresets | Partial mapping of success, error, alert, and gentle to ChimeNote[]. Overrides individual built-in chimes. |
Action, Promise, and Sound Types
Each object in the actions array accepts three public fields. Action callbacks receive the toast handle as their argument.
ToastAction field | Type and behavior |
|---|---|
label | string. Text displayed on the button. |
style | 'primary' | 'default', default 'default'. Button appearance. |
onClick | (handle: ToastHandle) => boolean | void. Return false to keep the toast open. |
PromiseOptions<T, E> has three optional branches. Each accepts PromiseValueSpec, which is a string, a ToastOptions object, or a function returning either. If the relevant success or error branch is omitted, the notification dismisses when the promise settles.
PromiseOptions field | Type and behavior |
|---|---|
loading | PromiseValueSpec<void>. Message or options shown during the pending state. |
success | PromiseValueSpec<T>. Value or function used when the promise resolves. |
error | PromiseValueSpec<E>. Value or function used when the promise rejects. |
SoundOption accepts a boolean, a built-in sound preset, an audio URL string, or ChimeNote[]. The presets gentle, alert, success, and error use the Web Audio API. configure({ soundPresets }) accepts a partial object with those four preset keys, each assigned an array of notes. Custom notes have the following fields.
ChimeNote field | Type and behavior |
|---|---|
frequency | number. Oscillator frequency in hertz. |
startOffset | number. Time offset from the start of the chime, in seconds. |
duration | number. Note duration in seconds. |
amplitude | number. Peak amplitude from 0 to 1. |
oscillatorType | Optional oscillator waveform: 'sine', 'square', 'sawtooth', or 'triangle'. Defaults to 'sine'. |
Styling and CSS Variables
chyrp follows prefers-color-scheme for its default light and dark colors. Apply class="dark" to <html> to force dark colors or class="light" to use the light palette.
Set the --tt-* custom properties in your CSS after the library stylesheet. For explicit dark colors, define the overrides in html.dark too, since the built-in dark-mode rules can supersede :root values.
-root {
--tt-bg: #fff;
--tt-title-color: #1e293b;
--tt-body-color: #475569;
--tt-info: #2563eb;
}
html.dark {
--tt-bg: #111827;
--tt-title-color: #f9fafb;
--tt-body-color: #d1d5db;
}
The default stylesheet exposes 25 CSS custom properties. These are their light-mode values.
UI and Text
| Variable | Purpose and light-mode default |
|---|---|
--tt-bg | Toast background, #fff. |
--tt-shadow | Resting shadow, 0 4px 12px rgba(0, 0, 0, 0.15). |
--tt-shadow-hover | Hover shadow, 0 6px 16px rgba(0, 0, 0, 0.18). |
--tt-title-color | Heading color, #111827. |
--tt-body-color | Message text color, #4b5563. |
--tt-channel-color | Channel label color, #9ca3af. |
Notification Accents and Buttons
| Variable | Purpose and light-mode default |
|---|---|
--tt-info | Info accent, #3b82f6. |
--tt-warning | Warning accent, #f59e0b. |
--tt-error | Error accent, #ef4444. |
--tt-loading | Loading accent, #6b7280. |
--tt-focus-ring | Keyboard focus outline, rgba(59, 130, 246, 0.5). |
--tt-action-bg | Default action background, #f3f4f6. |
--tt-action-color | Default action text, #374151. |
--tt-action-hover-bg | Default action hover background, #e5e7eb. |
--tt-action-primary-bg | Primary action background, #3b82f6. |
--tt-action-primary-hover-bg | Primary action hover background, #2563eb. |
Loading, Progress, and Overflow
| Variable | Purpose and light-mode default |
|---|---|
--tt-spinner-track | Spinner track, #e5e7eb. |
--tt-spinner-fill | Spinner accent, #6b7280. |
--tt-progress-bg | Timer progress track, rgba(0, 0, 0, 0.06). |
--tt-donut-track | Determinate progress track, rgba(0, 0, 0, 0.12). |
--tt-overflow-color | Overflow counter text, #4b5563. |
--tt-overflow-hover-color | Overflow counter hover text, #111827. |
--tt-overflow-bg | Overflow counter background, #fff. |
--tt-overflow-border | Overflow counter border, rgba(0, 0, 0, 0.06). |
--tt-overflow-shadow | Overflow counter shadow, 0 2px 6px rgba(0, 0, 0, 0.1). |
Optional Native Alert Replacement
interceptAlert() replaces window.alert() with info-style toast messages until its returned restore function is called. The override is opt-in. Native window.confirm() and window.prompt() are unaffected.
import { interceptAlert } from 'chyrp';
const restoreAlert = interceptAlert();
window.alert('Operation completed.');
// Restore the native browser dialog.
restoreAlert();
Alternatives & Related Resources
- Sonner-Style Toasts in Vanilla JavaScript – vanilla-sonner
- Modern Toast Popup JavaScript Library – EggyJS
- Material Design Toast & Snackbar Library with Action Buttons – MiniSnackbar
- Vanilla JS Info/Warning/Error/Danger Toast Notification Library – Toasteur.js







