React Simple Notify

A lightweight, performant notification library for React applications.
Live Demo →
Features
- ⚡ Lightning Fast - Optimized performance with minimal re-renders
- 📦 Tiny Bundle - Only ~5.6KB gzipped, zero dependencies
- 🎨 Fully Customizable - Complete control over styling and animations
- 🔧 TypeScript First - Built with TypeScript, full type safety
- 🌐 SSR Compatible - Works with Next.js, Remix, and other SSR frameworks
- ⏸️ Pause on Hover - Auto-dismiss timer pauses when users hover
- 🎯 Smart Positioning - 6 built-in positions with stack management
Installation
npm install react-simple-notify
yarn add react-simple-notify
pnpm add react-simple-notify
Quick Start
import { notify, NotifyContainers } from 'react-simple-notify';
function App() {
const showNotification = () => {
notify.open({
render: ({ onClose }) => (
<div className="notification">
<h4>Success!</h4>
<p>Your changes have been saved</p>
<button onClick={onClose}>Close</button>
</div>
),
});
};
return (
<>
<button onClick={showNotification}>Show Notification</button>
<NotifyContainers />
</>
);
}
API Reference
notify.open(options)
Opens a new notification.
Options
render | (args: NotifyRenderArgs) => ReactNode | Yes | - | Render function that returns notification content |
id | string | No | Auto-generated | Unique identifier for the notification |
duration | number | No | 3500 | Time in ms before auto-close. Set to 0 for persistent |
alignment | NotifyAlignment | No | bottomLeft | Position where notification appears |
pauseOnHover | boolean | No | false | Pause auto-dismiss timer on hover |
data | any | No | undefined | Custom data passed to render function |
Render Function Arguments
interface NotifyRenderArgs {
id: string;
duration: number;
alignment: NotifyAlignment;
onClose: () => void;
data?: any;
timeRemaining: number;
}
Example
import { notify, NotifyAlignment } from 'react-simple-notify';
notify.open({
alignment: NotifyAlignment.topRight,
duration: 5000,
pauseOnHover: true,
render: ({ onClose }) => (
<div className="notification success">
<span>✓ Operation completed successfully!</span>
<button onClick={onClose}>✕</button>
</div>
),
});
notify.update(id, options)
Updates an existing notification by ID.
const id = notify.open({
duration: 0,
data: { progress: 0 },
render: ({ data }) => (
<div>Loading... {data.progress}%</div>
),
});
notify.update(id, { data: { progress: 50 } });
notify.update(id, {
duration: 3000,
render: () => <div>✓ Complete!</div>,
});
notify.close(id)
Closes a specific notification by ID.
const id = notify.open({
render: () => <div>I can be closed programmatically</div>,
});
notify.close(id);
notify.closeAll()
Closes all active notifications.
notify.closeAll();
NotifyAlignment
Available positioning options:
enum NotifyAlignment {
topLeft = 'top-left',
topRight = 'top-right',
topCenter = 'top-center',
bottomLeft = 'bottom-left',
bottomRight = 'bottom-right',
bottomCenter = 'bottom-center',
}
Usage:
import { notify, NotifyAlignment } from 'react-simple-notify';
notify.open({
alignment: NotifyAlignment.topCenter,
render: () => <div>Notification at top center</div>,
});
Global Configuration
config.set(props)
Set global configuration for all notifications.
Options
alignment | NotifyAlignment | bottomLeft | Default position for all notifications |
reverse | boolean | false | New notifications appear at bottom of stack |
notifyComponent | React.ComponentType | Fragment | Wrapper component for notification content |
animationConfig | AnimationConfig | Default animations | Custom enter/exit animations |
maxNotifications | number | 0 | Maximum notifications per position (0 = unlimited) |
pauseOnHover | boolean | false | Global pause on hover setting |
Example: Basic Configuration
import { config, NotifyAlignment } from 'react-simple-notify';
config.set({
alignment: NotifyAlignment.topRight,
maxNotifications: 3,
pauseOnHover: true,
});
Example: Custom Wrapper Component
import { config } from 'react-simple-notify';
const NotificationWrapper = ({ children }) => (
<div className="notification-wrapper">
{children}
</div>
);
config.set({
notifyComponent: NotificationWrapper,
});
config.reset()
Reset configuration to default values.
config.reset();
Styling
CSS Custom Properties
Customize container spacing:
:root {
--rsn-container-padding: 16px;
--rsn-container-gap: 12px;
}
Custom Styles
Style your notifications with regular CSS:
notify.open({
render: () => (
<div className="my-notification">
<span>Custom styled notification</span>
</div>
),
});
.my-notification {
background: white;
padding: 16px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
Custom Animations
Override default animations:
import { config } from 'react-simple-notify';
config.set({
animationConfig: {
enter: {
duration: 300,
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
keyframes: ({ alignment }) => [
{ opacity: 0, transform: 'translateY(-20px)' },
{ opacity: 1, transform: 'translateY(0)' },
],
},
exit: {
duration: 200,
easing: 'ease-in',
keyframes: () => [
{ opacity: 1, transform: 'scale(1)' },
{ opacity: 0, transform: 'scale(0.8)' },
],
},
},
});
Animation Configuration
duration | number | Animation duration in milliseconds |
easing | string | CSS easing function |
keyframes | (args) => Keyframe[] | Function returning keyframes array |
Advanced Examples
Progress Notification
const showProgress = () => {
let progress = 0;
const id = notify.open({
duration: 0,
data: { progress: 0 },
render: ({ data }) => (
<div className="notification">
<h4>Uploading...</h4>
<div className="progress-bar">
<div style={{ width: `${data.progress}%` }} />
</div>
<p>{data.progress}%</p>
</div>
),
});
const interval = setInterval(() => {
progress += 10;
if (progress > 100) {
clearInterval(interval);
notify.update(id, {
duration: 3000,
render: () => (
<div className="notification success">
<h4>✓ Upload Complete!</h4>
</div>
),
});
} else {
notify.update(id, { data: { progress } });
}
}, 300);
};
Persistent Notification
notify.open({
duration: 0,
pauseOnHover: false,
render: ({ onClose }) => (
<div className="notification warning">
<h4>⚠ Action Required</h4>
<p>Please review your settings</p>
<button onClick={onClose}>Dismiss</button>
</div>
),
});
Progress Bar with Auto-Close
notify.open({
duration: 5000,
pauseOnHover: true,
render: ({ onClose, timeRemaining, duration }) => {
const progress = ((duration - timeRemaining) / duration) * 100;
return (
<div className="notification">
<h4>Auto-closing notification</h4>
<p>This will close in {Math.ceil(timeRemaining / 1000)}s</p>
<div className="progress-bar">
<div
className="progress-fill"
style={{ width: `${progress}%` }}
/>
</div>
<button onClick={onClose}>Close now</button>
</div>
);
},
});
Promise-based Notification
const saveData = async () => {
const id = notify.open({
duration: 0,
render: () => <div>Saving...</div>,
});
try {
await fetch('/api/save', { method: 'POST' });
notify.close(id);
notify.open({
render: () => <div>✓ Saved successfully!</div>,
});
} catch (error) {
notify.update(id, {
duration: 0,
render: ({ onClose }) => (
<div className="notification error">
<span>✕ Failed to save</span>
<button onClick={onClose}>Close</button>
</div>
),
});
}
};
Limit Maximum Notifications
import { config } from 'react-simple-notify';
config.set({
maxNotifications: 3,
});
for (let i = 0; i < 10; i++) {
notify.open({
render: () => <div>Notification {i + 1}</div>,
});
}
TypeScript
Full TypeScript support included. All types are exported:
import type {
NotifyRenderArgs,
NotifyOptions,
NotifyAlignment,
AnimationConfig,
ConfigProps,
} from 'react-simple-notify';
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
License
MIT © GruFFix
Links