Your design system, not ours
Ship toast UI that feels native to your product while twist-toast handles behavior.
Design-system-first notifications
Keep your own components. twist-toast handles queueing, timing, accessibility, dedupe, and provider orchestration with strict TypeScript inference.
Ship toast UI that feels native to your product while twist-toast handles behavior.
Infer payload types from variants so `toast.success(...)` is always compile-time safe.
Control visibility limits, refresh duplicate IDs, and dismiss programmatically.
Configure behavior without sacrificing branding
Model variants around your system tokens and trigger them through the generated API.
This mirrors runtime behavior: max visible stack + queued entries.
Profile updated
Avatar, bio, and links are now live.
Deployment still running
Auto-close delayed while background job is active.
Publish failed
Reusing ID will refresh this toast instead of duplicating it.
maxToasts
5
dedupe
refresh
Install, define variants, and trigger toasts in minutes
1. Install
npm install @twist-toast/react
2. Mount provider
import { ToastProvider } from "@twist-toast/react";import { toast } from "@/lib/toast";export default function RootLayout({children,}: {children: React.ReactNode}) {return <ToastProvider>{children}</ToastProvider>;}
3. Create typed toasts
// lib/toast.tsimport { createToast } from "@twist-toast/react";import type { ToastComponentProps } from "@twist-toast/react";import {SuccessToast, ErrorToast, WarningToast} from "./components/toasts";export const toast = createToast({success: SuccessToast,error: ErrorToast,warning: WarningToast,});
4. trigger toast
toast.success({ title: "Draft saved", description: "All changes synced." });toast.error({ title: "Failed to save draft", description: "Please try again." });toast.warning({ title: "Warning", description: "This action may be irreversible." });
Core options designed for predictable runtime control
| Option | Type | Default | Description |
|---|---|---|---|
| defaultDuration | number | 4000 | Fallback lifetime in milliseconds for each toast. |
| defaultPosition | ToastPosition | "top-right" | Viewport anchor used when a call does not pass a position. |
| maxToasts | number | 5 | Maximum visible items before new toasts enter the queue. |
| dedupe | "refresh" | "ignore" | "refresh" | Controls what happens when a toast is triggered with same ID. |
| scope | string | "default" | Isolation key for multiple independent toast systems. |
| Option | Type | Description |
|---|---|---|
| id | string | Stable identifier used for dedupe and targeted dismissal. |
| duration | number | Override duration for this single toast call. |
| position | ToastPosition | Per-toast anchor: top/bottom + left/center/right. |
| dismissOnClick | boolean | Allows click-to-close interaction for a toast instance. |
| role | "status" | "alert" | ARIA live region mode for accessibility semantics. |
| Method | Description |
|---|---|
| toast.variant(payload, options?) | Typed shortcut generated from each variant key. |
| toast.show(variant, payload, options?) | Dynamic variant trigger. |
| toast.dismiss(id) | Dismiss a single toast by ID. |
| toast.dismissAll() | Flush visible and queued toasts. |