Skip to content

JoshuaErney/chirp

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

55 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🐦 Chirp

Last Updated: 03/09/2026

A lightweight, dependency-free toast notification library built with vanilla JS and modern CSS. Forked from Butterup and rebuilt for simplicity, accessibility, and modern browser standards.


Features

  • Zero dependencies β€” vanilla JS and modern CSS only
  • Fully accessible β€” ARIA live regions, keyboard dismissal, screen reader announcements
  • Dark mode support via prefers-color-scheme
  • Reduced motion support via prefers-reduced-motion
  • Windows High Contrast mode support via forced-colors
  • Progress bar countdown with CSS custom properties
  • Deduplication β€” repeated toasts update in place instead of stacking
  • Global onToast and onDespawn callbacks for analytics and logging
  • Multiple toast types: success, error, warning, info
  • Multiple themes: glass, brutalist
  • Promise-based toasts for async workflows
  • Configurable position, icons, buttons, and callbacks

Installation

Manual Download chirp.js and chirp.css from this repo and reference them in your HTML.

<link
	rel="stylesheet"
	href="chirp.css" />
<script src="chirp.js"></script>

Basic Usage

chirp.toast({
	title: "Success",
	message: "Your changes have been saved.",
	type: "success",
	location: "top-right",
	icon: true,
	dismissable: true,
});

API

chirp.toast(options)

Option Type Default Description
title string null Bold heading text
message string null Body text
type string null success, error, warning, info
location string top-right top-right, top-center, top-left, bottom-right, bottom-center, bottom-left
icon boolean false Show a type-matched icon
customIcon string null Raw HTML/SVG to use as the icon
theme string null glass, brutalist
dismissable boolean false Dismiss on click, Enter, or Escape
progress boolean false Show a countdown progress bar
dedupe boolean false Update existing toast instead of spawning a duplicate
customHTML string null Inject custom HTML into the toast body
onClick function null Fires when the toast is clicked
onRender function null Fires immediately after the toast is added to the DOM
onTimeout function null Fires just before the toast auto-dismisses
primaryButton object null { text: string, onClick: function }
secondaryButton object null { text: string, onClick: function }

Returns the toastId string, which can be passed to chirp.despawnToast().


chirp.despawnToast(toastId, onClosed?)

Programmatically dismiss a toast by its ID. Optionally fires onClosed after the exit animation completes.

const id = chirp.toast({ message: "Hello!" });
chirp.despawnToast(id, () => console.log("Toast gone"));

chirp.clearAll()

Dismisses all active toasts, clears the dedup registry, and announces the action to screen readers.

chirp.clearAll();

chirp.promise(options)

Shows a loading toast that updates automatically based on a promise outcome.

Option Type Default Description
promise Promise required The promise to track
loadingMessage string 'Loading...' Message shown while pending
successMessage string 'Operation successful' Message shown on resolve
errorMessage string 'An error occurred' Message shown on reject
location string top-right Toast position
theme string null glass, brutalist
progress boolean false Show a countdown progress bar
chirp.promise({
	promise: fetch("/api/save"),
	loadingMessage: "Saving...",
	successMessage: "Saved successfully!",
	errorMessage: "Something went wrong.",
	location: "bottom-right",
});

Global Options

chirp.options.maxToasts = 5; // Max toasts visible at once (default: 5)
chirp.options.toastLife = 5000; // Auto-dismiss duration in ms (default: 5000)
chirp.options.onToast = null; // Fired when any toast is created
chirp.options.onDespawn = null; // Fired when any toast is removed

Examples

Progress bar

chirp.toast({
	title: "Uploading",
	message: "Your file is being uploaded.",
	type: "info",
	icon: true,
	progress: true,
	dismissable: true,
});

Deduplication

// Repeated calls update the existing toast instead of stacking
chirp.toast({
	title: "Validation error",
	message: "Please fill in all required fields.",
	type: "error",
	icon: true,
	dedupe: true,
});

Global callbacks

// Set once β€” fires for every toast in your app
chirp.options.onToast = (toast) => analytics.track("toast_shown", { id: toast.id });
chirp.options.onDespawn = (toast) => analytics.track("toast_dismissed", { id: toast.id });

With buttons

chirp.toast({
	title: "Delete item?",
	message: "This action cannot be undone.",
	type: "error",
	icon: true,
	primaryButton: {
		text: "Delete",
		onClick: () => deleteItem(),
	},
	secondaryButton: {
		text: "Cancel",
		onClick: () => console.log("Cancelled"),
	},
});

Custom icon and theme

chirp.toast({
	message: "Copied to clipboard.",
	theme: "glass",
	icon: true,
	customIcon: '<svg aria-hidden="true" focusable="false">...</svg>',
	dismissable: true,
});

Accessibility

Chirp is built with accessibility as a core requirement, not an afterthought.

  • The toaster container has role="region" and aria-label="Notifications" for screen reader landmark navigation
  • The toast rack uses aria-live="polite" by default, switching to aria-live="assertive" for error type toasts
  • Each toast has role="status" or role="alert" depending on type
  • Dismissable toasts are keyboard focusable (tabindex="0") and respond to Enter and Escape
  • All decorative icons include aria-hidden="true" and focusable="false"
  • chirp.clearAll() announces dismissal to screen readers via a temporary live region
  • Focus styles use :focus-visible and match each toast type's colour
  • The progress bar is hidden from assistive technology via aria-hidden="true"

Browser Support

Chirp targets modern browsers and uses the following features:

  • aria-live / ARIA roles β€” universal
  • prefers-reduced-motion β€” all modern browsers
  • prefers-color-scheme β€” all modern browsers
  • forced-colors β€” Chromium 89+, Firefox 89+
  • :focus-visible β€” all modern browsers
  • :is() selector β€” all modern browsers
  • CSS custom properties β€” all modern browsers
  • backdrop-filter (glass theme) β€” all modern browsers; no fallback in Firefox pre-103

Attribution

Chirp is forked from Butterup by nlanger, distributed under the MIT License.


License

MIT β€” free to use in personal and commercial projects.


Contributing

Fork the repo, make your changes, and open a pull request. Bug fixes and improvements are welcome.

About

🐦 Chirp β€” A lightweight, dependency-free toast notification library built with vanilla JS and modern CSS. Forked from Butterup and rebuilt for simplicity and modern browser standards.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • CSS 43.3%
  • JavaScript 43.2%
  • HTML 13.5%