A beautiful, animated toast notification system for React Native with gesture support and smooth animations.
- 🎨 Beautiful animated toasts with smooth entry/exit animations
- 👆 Swipe to dismiss gestures
- 🎯 Multiple toast types (success, error, warning, info)
- ⚡ Easy to use hooks
- 🎭 Customizable appearance and actions
- 📱 Works with Expo and bare React Native
- 🔄 Auto-dismiss with configurable duration
- 🌍 TypeScript support
- 🎛️ NEW: Custom animation durations and types
- 📍 NEW: Configurable toast positions (top, bottom, center)
- 🎨 NEW: Custom styling support
- ⚙️ NEW: Global configuration options
- 🔧 NEW: Per-toast configuration overrides
bun add hn-react-native-toaster
# or
npm install hn-react-native-toaster
# or
yarn add hn-react-native-toaster
```### Peer Dependencies
Make sure you have these dependencies installed:
```bash
bun add react-native-reanimated react-native-gesture-handler react-native-safe-area-context zustand
# or
npm install react-native-reanimated react-native-gesture-handler react-native-safe-area-context zustandimport { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* Your app content */}
</GestureHandlerRootView>
);
}import { ToastContainer } from 'hn-react-native-toaster';
export default function App() {
return (
<View style={{ flex: 1 }}>
{/* Your app content */}
<ToastContainer />
</View>
);
}import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { useToast, ToastContainer } from 'hn-react-native-toaster';
function MyComponent() {
const toast = useToast();
const showSuccess = () => {
toast.success('Operation completed successfully!', 'Success');
};
const showError = () => {
toast.error('Something went wrong', 'Error');
};
return (
<View>
<TouchableOpacity onPress={showSuccess}>
<Text>Show Success Toast</Text>
</TouchableOpacity>
<TouchableOpacity onPress={showError}>
<Text>Show Error Toast</Text>
</TouchableOpacity>
<ToastContainer />
</View>
);
}const toast = useToast();
// Basic toast methods
toast.success(message, title?, duration?)
toast.error(message, title?, duration?)
toast.warning(message, title?, duration?)
toast.info(message, title?, duration?)
// Control methods
toast.hide(id)
toast.clear()Specialized hook for API operations:
const apiToast = useApiToast();
apiToast.handleApiSuccess('Data loaded successfully!');
apiToast.handleApiError(error);
apiToast.handleApiLoading('Loading...');Specialized hook for form validation:
const formToast = useFormToast();
formToast.validationError('Please enter a valid email');
formToast.saveSuccess('Form saved successfully!');
formToast.saveError('Failed to save form');- success: Green toast for successful operations
- error: Red toast for errors and failures
- warning: Orange toast for warnings
- info: Blue toast for informational messages
Configure global settings that apply to all toasts:
const toast = useToast();
// Configure global settings
toast.configure({
position: 'bottom', // 'top' | 'bottom' | 'center'
animationConfig: {
entry: {
duration: 500,
type: 'spring', // 'spring' | 'timing'
damping: 10,
stiffness: 100,
},
exit: {
duration: 300,
type: 'timing',
},
},
autoHide: true, // Auto-dismiss toasts
swipeEnabled: true, // Enable swipe to dismiss
});Override global settings for individual toasts:
// Custom animation duration
toast.success('Slow animation!', 'Watch me!', {
animationConfig: {
entry: { duration: 800, type: 'spring' },
exit: { duration: 600, type: 'timing' },
},
});
// Custom position
toast.warning('I appear in the center!', 'Centered', {
position: 'center',
});
// Disable swipe for specific toast
toast.error('Cannot swipe me!', 'Persistent', {
swipeEnabled: false,
autoHide: false,
});Apply custom styles to any part of the toast:
toast.success('Beautiful toast!', 'Custom Style', {
customStyles: {
container: {
backgroundColor: '#6366F1',
borderRadius: 20,
borderLeftWidth: 0,
shadowColor: '#6366F1',
shadowOpacity: 0.5,
shadowRadius: 15,
},
title: {
color: '#FFFFFF',
fontSize: 18,
fontWeight: 'bold',
},
message: {
color: '#E0E7FF',
fontSize: 16,
},
icon: {
fontSize: 20,
},
closeButton: {
backgroundColor: 'rgba(255, 255, 255, 0.2)',
},
actionButton: {
backgroundColor: '#4F46E5',
},
},
});Choose between different animation types:
// Spring animation (bouncy, natural)
toast.info('Spring animation!', 'Bouncy', {
animationConfig: {
entry: {
type: 'spring',
damping: 15, // Higher = less bouncy
stiffness: 150, // Higher = faster
duration: 300,
},
},
});
// Timing animation (linear, precise)
toast.info('Timing animation!', 'Smooth', {
animationConfig: {
entry: {
type: 'timing',
duration: 400,
},
},
});Control where toasts appear on screen:
// Top position (default)
toast.success('I appear at the top!', '', { position: 'top' });
// Bottom position
toast.success('I appear at the bottom!', '', { position: 'bottom' });
// Center position
toast.success('I appear in the center!', '', { position: 'center' });const toast = useToast();
// Basic toast methods with optional config
toast.success(message, title?, config?)
toast.error(message, title?, config?)
toast.warning(message, title?, config?)
toast.info(message, title?, config?)
// Control methods
toast.hide(id)
toast.clear()
toast.configure(globalConfig) // New: Set global configurationinterface ToastConfig {
position?: 'top' | 'bottom' | 'center';
animationConfig?: {
entry?: {
duration?: number;
type?: 'spring' | 'timing';
damping?: number; // Spring only
stiffness?: number; // Spring only
};
exit?: {
duration?: number;
type?: 'spring' | 'timing';
damping?: number; // Spring only
stiffness?: number; // Spring only
};
};
customStyles?: {
container?: ViewStyle;
content?: ViewStyle;
title?: TextStyle;
message?: TextStyle;
icon?: TextStyle;
closeButton?: ViewStyle;
closeText?: TextStyle;
actionButton?: ViewStyle;
actionText?: TextStyle;
};
autoHide?: boolean;
swipeEnabled?: boolean;
}- success: Green toast for successful operations
- error: Red toast for errors and failures
- warning: Orange toast for warnings
- info: Blue toast for informational messages
For advanced use cases, you can access the store directly:
import { useToastStore } from 'hn-react-native-toaster';
const { toasts, showToast, hideToast, clearAllToasts } = useToastStore();Check out the example app in the /example folder to see all features in action.
cd example
bun install
bun run startTo develop and test the package locally:
# In the main package directory
bun link
# In your test project
bun link hn-react-native-toaster# Clone and setup
git clone <repository-url>
cd react-toaster
# Install dependencies
bun install
# Link the package and setup example
bun run link:local
bun run setup:example
# Start development
bun run exampleAfter making changes to the package:
# Rebuild if needed
bun run build
# The linked package will automatically reflect changes
# Just reload your app to see updatesWe welcome contributions! Please see our Contributing Guidelines for details on how to:
- Report bugs
- Suggest new features
- Submit pull requests
- Set up the development environment
Before contributing, please read our Code of Conduct.
If you discover a security vulnerability, please follow our Security Policy for responsible disclosure.
See CHANGELOG.md for a detailed list of changes and version history.
This project is licensed under the MIT License - see the LICENSE file for details.
- 🐛 Bug Reports: Create an issue
- 💡 Feature Requests: Start a discussion
- ❓ Questions: Check existing discussions or create a new one
nyambogahezron - GitHub
Made with ❤️ for the React Native community
