@rskm/react-sparkalert is a simple, lightweight, and fully customizable toast notification library built for React.
- π 3 Beautiful Themes - Light, Dark, and Colored modes
- π 4 Smooth Animations - Slide, Bounce, Zoom, and Flip transitions
- π± Fully Responsive - Perfect display on all screen sizes
- π― 6 Position Options - Place toasts anywhere on the screen
- π« Smooth Animations - Professional enter/exit animations
- π¦ Lightweight - Minimal bundle size (~15KB minified + gzipped)
- π· TypeScript Support - Fully typed for better DX
- β‘ Zero Dependencies - Only requires React
- π― Easy Integration - Simple API, quick setup
- π Comprehensive Documentation - Detailed guides and examples
- π 5 Toast Types - Success, Error, Warning, Info, Loading
- β±οΈ Auto-Dismiss - Configurable auto-close timing
- π±οΈ Interactive Controls - Pause on hover, drag to dismiss
- π Progress Bar - Visual countdown indicator
- π¨ Custom Styling - Easy to customize with CSS
- π Promise Support - Handle async operations elegantly
- π― Multi-Position - Display toasts at multiple positions simultaneously
- β ARIA labels for screen readers
- β Keyboard navigation support
- β Proper contrast ratios
- β Semantic HTML structure
# Using npm
npm install @rskm/react-sparkalert
# Using yarn
yarn add @rskm/react-sparkalert
# Using pnpm
pnpm add @rskm/react-sparkalertImport CSS: Import the CSS file in your main entry file (like App.tsx/app.jsx, main.tsx/main.jsx, or layout.tsx/jsx for Next.js).
import '@rskm/react-sparkalert/dist/index.css'import { ToastContainer } from '@rskm/react-sparkalert';
function App() {
return (
<>
<YourApp />
<ToastContainer />
</>
);
}
export default App;import { toast } from '@rskm/react-sparkalert';
function MyComponent() {
const showToast = () => {
toast.success('Operation successful!');
};
return <button onClick={showToast}>Show Toast</button>;
}import { toast } from '@rskm/react-sparkalert';
// Success notification
toast.success('Profile updated successfully!');
// Error notification
toast.error('Failed to save changes');
// Warning notification
toast.warning('Please verify your email');
// Info notification
toast.info('New features available');
// Loading notification
toast.loading('Processing your request...');Place toasts at 6 different positions:
toast.success('Top Right!', { position: 'top-right' });
toast.success('Top Left!', { position: 'top-left' });
toast.success('Top Center!', { position: 'top-center' });
toast.success('Bottom Right!', { position: 'bottom-right' });
toast.success('Bottom Left!', { position: 'bottom-left' });
toast.success('Bottom Center!', { position: 'bottom-center' });Choose from 3 beautiful themes:
// Light theme (default)
toast.success('Light theme', { theme: 'light' });
// Dark theme
toast.success('Dark theme', { theme: 'dark' });
// Colored theme
toast.success('Colored theme', { theme: 'colored' });Apply smooth animations:
toast.success('Slide transition', { transition: 'slide' });
toast.success('Bounce transition', { transition: 'bounce' });
toast.success('Zoom transition', { transition: 'zoom' });
toast.success('Flip transition', { transition: 'flip' });Control when toasts disappear:
// Auto close after 5 seconds
toast.success('Will close in 5s', { autoClose: 5000 });
// Disable auto close
toast.info('Will not auto close', { autoClose: false });
// Default is 5000ms (5 seconds)
toast.success('Default timing');// Pause on hover (default: true)
toast.success('Hover to pause', { pauseOnHover: true });
// Disable pause on hover
toast.info('Cannot pause', { pauseOnHover: false });
// Enable dragging (default: true)
toast.success('Drag to dismiss', { draggable: true });
// Disable dragging
toast.info('Cannot drag', { draggable: false });// Get toast ID
const toastId = toast.info('This can be dismissed');
// Dismiss specific toast
toast.dismiss(toastId);
// Dismiss all toasts
toast.dismissAll();const toastId = toast.loading('Uploading file...');
// Update after some time
setTimeout(() => {
toast.update(toastId, {
type: 'success',
message: 'File uploaded successfully!',
autoClose: 3000,
});
}, 2000);Handle async operations elegantly:
const myPromise = fetch('/api/data');
toast.promise(
myPromise,
{
loading: 'Loading data...',
success: 'Data loaded successfully!',
error: 'Failed to load data',
}
);
// With dynamic messages
toast.promise(
fetchUsers(),
{
loading: 'Fetching users...',
success: (data) => `Loaded ${data.length} users`,
error: (err) => `Error: ${err.message}`,
}
);toast.success(
<div>
<strong>Success!</strong>
<p>Your changes have been saved.</p>
</div>
);
toast.error(
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span>β</span>
<div>
<strong>Error occurred</strong>
<p>Please try again later</p>
</div>
</div>
);// Custom CSS class
toast.success('Custom styled', {
className: 'my-custom-toast',
bodyClassName: 'my-custom-body',
progressClassName: 'my-custom-progress'
});
// Inline styles
toast.info('Inline styled', {
style: {
background: 'linear-gradient(to right, #667eea, #764ba2)',
color: 'white',
}
});toast.success('With callbacks', {
onOpen: () => console.log('Toast opened'),
onClose: () => console.log('Toast closed'),
});Configure the container with these props:
<ToastContainer
position="top-right" // Default position
autoClose={5000} // Default auto close time
pauseOnHover={true} // Pause on hover
draggable={true} // Enable dragging
closeButton={true} // Show close button
progressBar={true} // Show progress bar
theme="colored" // Theme: light | dark | colored
transition="flip" // Animation: slide | bounce | zoom | flip
limit={5} // Max toasts visible
newestOnTop={true} // Stack order
className="custom-container" // Custom CSS class
style={{}} // Inline styles
/>| Prop | Type | Default | Description |
|---|---|---|---|
position |
ToastPosition |
'top-right' |
Default position for toasts |
autoClose |
number | false |
5000 |
Auto close time in ms (false to disable) |
pauseOnHover |
boolean |
true |
Pause timer on hover |
draggable |
boolean |
true |
Enable drag to dismiss |
closeButton |
boolean |
true |
Show close button |
progressBar |
boolean |
true |
Show progress bar |
theme |
'light' | 'dark' | 'colored' |
'colored' |
Toast theme |
transition |
'bounce' | 'slide' | 'zoom' | 'flip' |
'flip' |
Animation type |
limit |
number |
5 |
Max number of toasts |
newestOnTop |
boolean |
true |
Stack order |
className |
string |
'' |
Custom CSS class |
style |
React.CSSProperties |
{} |
Inline styles |
Per-toast configuration:
toast.success('Message', {
position: 'top-right', // Position
autoClose: 5000, // Auto close time
pauseOnHover: true, // Pause on hover
draggable: true, // Draggable
closeButton: true, // Close button
progressBar: true, // Progress bar
theme: 'colored', // Theme
transition: 'flip', // Transition
icon: <CustomIcon />, // Custom icon (or false to hide)
className: 'custom-toast', // Custom class
bodyClassName: 'body', // Body class
progressClassName: 'prog', // Progress class
style: {}, // Inline styles
onOpen: () => {}, // Open callback
onClose: () => {}, // Close callback
});| Option | Type | Default | Description |
|---|---|---|---|
type |
'success' | 'error' | 'warning' | 'info' | 'loading' |
- | Toast type |
position |
ToastPosition |
'top-right' |
Toast position |
autoClose |
number | false |
5000 |
Auto close time |
pauseOnHover |
boolean |
true |
Pause on hover |
draggable |
boolean |
true |
Enable dragging |
closeButton |
boolean |
true |
Show close button |
progressBar |
boolean |
true |
Show progress bar |
theme |
'light' | 'dark' | 'colored' |
'colored' |
Theme |
transition |
'bounce' | 'slide' | 'zoom' | 'flip' |
'flip' |
Animation |
icon |
ReactNode | false |
- | Custom icon |
className |
string |
- | Custom CSS class |
bodyClassName |
string |
- | Body CSS class |
progressClassName |
string |
- | Progress CSS class |
style |
CSSProperties |
- | Inline styles |
onOpen |
() => void |
- | Open callback |
onClose |
() => void |
- | Close callback |
Import CSS: Import the CSS file in your main entry file (like App.tsx/jsx, main.tsx/jsx, or layout.tsx/jsx for Next.js).
import '@rskm/react-sparkalert/dist/index.css'import { toast, ToastContainer } from '@rskm/react-sparkalert';
function App() {
const handleSuccess = () => {
toast.success('Operation completed successfully!');
};
const handleError = () => {
toast.error('Something went wrong!');
};
return (
<div>
<button onClick={handleSuccess}>Success</button>
<button onClick={handleError}>Error</button>
<ToastContainer />
</div>
);
}const handleSubmit = async (data) => {
const submitPromise = api.submitForm(data);
toast.promise(
submitPromise,
{
loading: 'Submitting form...',
success: 'Form submitted successfully!',
error: 'Failed to submit form',
}
);
};const processData = async () => {
const step1 = toast.loading('Step 1: Validating...');
await validate();
toast.update(step1, {
type: 'success',
message: 'Step 1: Validated β',
autoClose: 2000
});
const step2 = toast.loading('Step 2: Processing...');
await process();
toast.update(step2, {
type: 'success',
message: 'Step 2: Processed β',
autoClose: 2000
});
toast.success('All steps completed!');
};const NotificationButton = () => {
const notify = () => {
toast.info('You have 3 new messages', {
position: 'top-right',
autoClose: 5000,
icon: <BellIcon />,
});
};
return <button onClick={notify}>Check Notifications</button>;
};/* styles.css */
.my-custom-toast {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}
.my-custom-body {
font-weight: 600;
font-size: 16px;
}toast.success('Custom styled!', {
className: 'my-custom-toast',
bodyClassName: 'my-custom-body',
});toast.success('Inline styled!', {
style: {
background: '#1e293b',
color: '#f1f5f9',
borderRadius: '12px',
padding: '20px',
fontSize: '16px',
}
});import { createContext, useContext } from 'react';
import { toast } from '@rskm/react-sparkalert';
const NotificationContext = createContext();
export const NotificationProvider = ({ children }) => {
const notify = {
success: (msg) => toast.success(msg, { position: 'top-right' }),
error: (msg) => toast.error(msg, { position: 'top-right' }),
info: (msg) => toast.info(msg, { position: 'bottom-left' }),
};
return (
<NotificationContext.Provider value={notify}>
{children}
</NotificationContext.Provider>
);
};
export const useNotification = () => useContext(NotificationContext);useEffect(() => {
const handleError = (error) => {
toast.error(error.message, {
position: 'top-center',
autoClose: false,
});
};
window.addEventListener('error', handleError);
return () => window.removeEventListener('error', handleError);
}, []);React SparkAlert is fully responsive and works perfectly on all devices:
- β Desktop - Full-width toasts with all features
- β Tablet - Optimized layout and spacing
- β Mobile - Touch-friendly, swipe to dismiss
- β Chrome (latest)
- β Firefox (latest)
- β Safari (latest)
- β Edge (latest)
- β Opera (latest)
toast.success(message, options?) // Show success toast
toast.error(message, options?) // Show error toast
toast.warning(message, options?) // Show warning toast
toast.info(message, options?) // Show info toast
toast.loading(message, options?) // Show loading toast
toast.dismiss(id) // Dismiss specific toast
toast.dismissAll() // Dismiss all toasts
toast.update(id, options) // Update existing toast
toast.promise(promise, messages, options?) // Handle promiseMIT Β© Sumon Mitra (SRKM) This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by popular toast libraries
- Built with β€οΈ for the React community
- Thanks to all contributors
- π§ Email: sumonmit678@gmail.com
Made with β€οΈ by Sumon Mitra
β Star us on GitHub if you like this project!