@shaad2207/react-native-custom-toast
v1.0.2
Published
A lightweight, customizable, gesture-enabled toast notification library for React Native with zero external state dependencies.
Maintainers
Readme
@shaad2207/react-native-custom-toast 🍞
A lightweight, high-performance, gesture-driven toast notification library for React Native with zero external state dependencies (no MobX/Redux required).
Includes smooth entry/spring animations, swipe-to-dismiss gesture support, automatic dark/light theming, built-in vector icons, haptic feedback, and a simple imperative API.
✨ Features
- 🚀 Zero External State Dependencies: Completely self-contained event manager. Works with any state management (Redux, MobX, Zustand, or none).
- ⚡ Call from Anywhere: Trigger toasts inside components, async thunks, axios interceptors, or utility functions using
toast.success(),toast.error(), etc. - 👆 Swipe-to-Dismiss: Smooth vertical swipe gestures to dismiss notifications.
- 🎨 Modern Sleek Aesthetics: Dark mode by default (
#1E293Bcard with subtle borders), light mode support, and custom styling overrides. - 🔄 Loading State with Spinner: Real-time rotating loader with easy
.update()transition to success or error. - 📳 Haptic Feedback: Rich, tactile feedback on toast entry powered by
react-native-haptic-feedbackwith distinct feedback patterns for success, error, and info/loading (configurable & customizable). - 🛡️ Safe Area Support: Automatically respects status bar and safe area insets on iOS and Android.
- 📦 TypeScript First: Full type definitions for all options and methods.
📦 Installation
npm install @shaad2207/react-native-custom-toast react-native-haptic-feedback
# or
yarn add @shaad2207/react-native-custom-toast react-native-haptic-feedback
# or
pnpm add @shaad2207/react-native-custom-toast react-native-haptic-feedbackiOS Note: Don't forget to run
pod installin yourios/folder after installing.
📱 Android Configuration (Vibration Permission)
To enable haptic vibration feedback on Android devices, make sure to add the VIBRATE permission in your android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Required for haptic vibration feedback -->
<uses-permission android:name="android.permission.VIBRATE" />
<application ...>
...
</application>
</manifest>Note: If
android.permission.VIBRATEis not included in your manifest, the haptic call will fail gracefully without crashing your app. You can also disable haptics globally by settinghaptic={false}on<Toaster />, or per individual toast via{ haptic: false }.
🚀 Quick Start
1. Mount <Toaster /> at the root of your application
Add the <Toaster /> component once, typically in your root App.tsx or main layout container:
import React from 'react';
import { View } from 'react-native';
import { Toaster } from '@shaad2207/react-native-custom-toast';
export default function App() {
return (
<View style={{ flex: 1 }}>
{/* Your App Navigation / Screens */}
{/* Toast Notification Container */}
<Toaster />
</View>
);
}2. Trigger toasts from anywhere!
import { toast } from '@shaad2207/react-native-custom-toast';
// Success
toast.success('Profile updated successfully!');
// Error
toast.error('Network request failed. Please try again.');
// Info
toast.info('New feature available in settings');
// Generic show with custom duration
toast.show('Custom message', {
duration: 4000,
});🔄 Loading & Async Update Example
Display a persistent loading spinner and update it when the asynchronous operation completes:
import { toast } from 'react-native-custom-toast';
const handleUpload = async () => {
const toastId = toast.loading('Uploading photo...');
try {
await api.uploadPhoto();
// Update loading toast to success
toast.update(toastId, {
type: 'success',
message: 'Photo uploaded!',
duration: 3000,
});
} catch (error) {
// Update to error
toast.update(toastId, {
type: 'error',
message: 'Upload failed!',
duration: 4000,
});
}
};🔘 Action Buttons & Click Callbacks
toast.show('Item moved to trash', {
duration: 5000,
action: {
label: 'UNDO',
onPress: () => {
restoreItem();
},
},
onPress: () => {
console.log('Toast card tapped');
},
onClose: () => {
console.log('Toast dismissed');
},
});📳 Haptic Feedback Options
By default, toasts automatically trigger distinct haptic feedback based on their type:
toast.success()->'notificationSuccess'toast.error()->'notificationError'toast.info()/toast.loading()->'impactLight'
You can also customize the haptic feedback type or disable it on a per-toast basis:
// Custom haptic pattern
toast.show('Payment confirmed!', {
type: 'success',
hapticType: 'notificationSuccess',
});
// Heavy impact feedback
toast.show('Warning!', {
hapticType: 'impactHeavy',
});
// Disable haptics for a specific toast
toast.info('Silent update', {
haptic: false,
});🎨 Configuration & Props
<Toaster /> Props
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| position | 'top' \| 'bottom' | 'top' | Screen position for toasts |
| maxToasts | number | 3 | Maximum toasts visible simultaneously |
| offset | number | Safe area inset | Custom top/bottom offset in pixels |
| defaultDuration | number | 3000 | Default auto-dismiss duration (ms) |
| theme | 'dark' \| 'light' \| ToastTheme | 'dark' | Visual theme or custom color object |
| haptic | boolean | true | Enable/disable haptic feedback on appearance (powered by react-native-haptic-feedback) |
| hapticType | HapticType | type-based | Custom default haptic feedback pattern (e.g. 'impactLight', 'notificationSuccess') |
| hapticOptions | HapticOptions | { enableVibrateFallback: true } | Custom configuration options for react-native-haptic-feedback |
| containerStyle | ViewStyle | — | Custom style for toast container |
| toastStyle | ViewStyle | — | Custom style for toast card |
| messageStyle | TextStyle | — | Custom style for text message |
| renderIcon | (type, toast) => ReactNode | — | Custom icon renderer callback |
| onVibrate | () => void | — | Custom vibration callback (overrides default haptic feedback) |
Custom Theming
You can pass a custom theme object to <Toaster />:
<Toaster
theme={{
backgroundColor: '#0F172A',
textColor: '#F8FAFC',
borderColor: 'rgba(255, 255, 255, 0.15)',
borderRadius: 12,
successColor: '#10B981',
errorColor: '#EF4444',
infoColor: '#3B82F6',
loadingColor: '#94A3B8',
}}
/>🪝 React Hook: useToast
If you prefer using hooks inside React components:
import React from 'react';
import { Button, View } from 'react-native';
import { useToast } from 'react-native-custom-toast';
export const MyComponent = () => {
const { success, error } = useToast();
return (
<View>
<Button title="Save" onPress={() => success('Saved!')} />
<Button title="Delete" onPress={() => error('Deleted!')} />
</View>
);
};🛠️ API Reference
toast.show(message, options?): Show a toast with custom options.toast.success(message, options?): Show a success toast with green icon.toast.error(message, options?): Show an error toast with red icon.toast.info(message, options?): Show an informational toast with blue icon.toast.loading(message, options?): Show an infinite loading toast with spinner.toast.update(id, updates): Update an existing toast (e.g., transition from loading to success).toast.remove(id)/toast.hide(id): Dismiss a specific toast.toast.clearAll(): Dismiss all active toasts immediately.
📄 License
MIT © 2026
