English | 한국어
A React toast package built for practical react-hot-toast replacement quality.
@ilokesto/toast provides a provider-scoped toast runtime, a familiar toast.* facade, a polished default renderer, headless hooks, and an optional top-layer transport. Internally it uses @ilokesto/overlay for presence lifecycle only, while toast policy and rendering stay inside this package.
- Familiar facade:
toast(),toast.success(),toast.error(),toast.loading(),toast.custom(),toast.promise() - Provider-scoped runtimes separated by
toasterId - Default
Toasterwith built-in card UI, animated status icons, spinner, and enter/exit motion - Per-toast options such as
style,className,icon,iconTheme,removeDelay,position,duration, andariaProps toastOptionsmerge order of global → per-type → per-toast options- Headless
useToaster()for custom renderers - Optional
transport="top-layer"mode powered by manual popover
pnpm add @ilokesto/toast react react-domor
npm install @ilokesto/toast react react-domimport { Toaster, toast } from '@ilokesto/toast';
function App() {
return (
<>
<button onClick={() => toast.success('Saved successfully')}>Show toast</button>
<Toaster />
</>
);
}import { Toaster, toast } from '@ilokesto/toast';
async function savePost() {
return fetch('/api/posts', { method: 'POST' });
}
toast.promise(savePost(), {
loading: 'Saving post…',
success: 'Post saved',
error: (error) => `Save failed: ${String(error)}`,
});
export function App() {
return <Toaster />;
}import { Toaster } from '@ilokesto/toast';
export function App() {
return (
<Toaster>
{(toast, { dismiss }) => (
<button onClick={dismiss}>
{toast.message}
</button>
)}
</Toaster>
);
}import { ToastBar, Toaster } from '@ilokesto/toast';
export function App() {
return (
<Toaster>
{(toast) => (
<ToastBar toast={toast}>
{({ icon, message }) => (
<>
{message}
{icon}
</>
)}
</ToastBar>
)}
</Toaster>
);
}@ilokesto/toast adds an extra rendering mode that react-hot-toast does not provide:
<Toaster transport="top-layer" />This uses manual popover when the browser supports it and falls back to inline rendering when it does not.
useToaster() exposes the visible toast list and runtime helpers:
const { toasts, handlers } = useToaster();Available handlers:
updateHeightstartPauseendPausecalculateOffset
This hook is intended for advanced integrations that run under the mounted Toaster context.
src/
components/
ToastBar.tsx
ToastProvider.tsx
Toaster.tsx
icons.tsx
core/
createToastRuntime.ts
createToastStore.ts
registry.ts
toast.ts
utils.ts
hooks/
useToaster.ts
useToastItems.ts
types/
toast.ts
index.ts
Toaster.tsx→ mounts the visible toast stack, configures runtime view options, and provides the default containerToastBar.tsx→ composable default renderer primitive for a single toast rowicons.tsx→ built-in spinner and status icon components used by the default rendererToastProvider.tsx→ creates and registers provider-scoped runtimes bytoasterId
toast.ts→ the publictoast.*facadecreateToastRuntime.ts→ toast policy layer for ids, timers, promise transitions, dismiss/remove behavior, and visible-set calculationcreateToastStore.ts→ raw toast state storeregistry.ts→ runtime registration bytoasterIdutils.ts→ default durations, ids, icon themes, and small helpers
useToaster.ts→ headless hook returning{ toasts, handlers }useToastItems.ts→ subscribes to the current visible toast items
toast.ts→ public contracts for runtime APIs, props, item state, and options
- re-exports the public runtime, renderer, hook, and type surface
- values →
toast,Toaster,ToastBar,ToastIcon,useToaster,useToastItems,createToastRuntime - types →
ToastBarProps,ToastOptions,DefaultToastOptions,ToasterProps,UseToasterResult, and related toast contracts
If you are moving from react-hot-toast, see MIGRATION_FROM_REACT_HOT_TOAST.md.
pnpm install
pnpm run buildBuild outputs are generated in the dist directory.
MIT