npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@shaquillehinds/react-native-in-app-notification

v0.1.0

Published

A simple in app notification for react native that just works.

Downloads

511

Readme

@shaquillehinds/react-native-in-app-notification

npm version License: MIT

A beautiful, customizable, and performant in-app notification system for React Native that just works. Built with React Native Reanimated for smooth 60fps animations and gesture support.

✨ Features

  • 🎨 Fully Customizable - Complete control over styling, sizing, and behavior
  • 📱 Cross-Platform - Works seamlessly on iOS and Android
  • 🎭 Flexible Content - Support for both data-driven notifications and custom components
  • 🖼️ Image Support - Automatic detection and optimization for expo-image, react-native-fast-image, or standard Image
  • Performant - Built on Reanimated for smooth 60fps animations
  • 👆 Gesture Support - Swipe up to dismiss notifications
  • 📐 Responsive - Automatic orientation and screen size handling
  • 🎯 TypeScript - Full TypeScript support with comprehensive type definitions
  • 🎪 Queue Management - Smart notification stacking and timing
  • 🔔 Lifecycle Hooks - onEnter, onLeave, and onPress callbacks

📦 Installation

npm install @shaquillehinds/react-native-in-app-notification

or

yarn add @shaquillehinds/react-native-in-app-notification

Peer Dependencies

This package requires the following peer dependencies:

npm install react-native-reanimated react-native-gesture-handler

or

yarn add react-native-reanimated react-native-gesture-handler

Note: This package depends on @shaquillehinds/react-native-essentials which will be installed automatically.

Additional Configuration

For React Native Reanimated, add the Babel plugin to your babel.config.js:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['react-native-reanimated/plugin'],
};

For React Native Gesture Handler, wrap your app with GestureHandlerRootView:

import { GestureHandlerRootView } from 'react-native-gesture-handler';

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      {/* Your app code */}
    </GestureHandlerRootView>
  );
}

🚀 Quick Start

1. Wrap Your App with the Provider

import { InAppNotificationProvider } from '@shaquillehinds/react-native-in-app-notification';

export default function App() {
  return (
    <InAppNotificationProvider>
      {/* Your app code */}
    </InAppNotificationProvider>
  );
}

2. Use the Hook to Show Notifications

import { useInAppNotification } from '@shaquillehinds/react-native-in-app-notification';

function MyComponent() {
  const { addNotification } = useInAppNotification();

  const showNotification = () => {
    addNotification({
      content: {
        type: 'data',
        payload: {
          title: 'Success!',
          message: 'Your action was completed successfully.',
        },
      },
      duration: 3000,
    });
  };

  return (
    <Button title="Show Notification" onPress={showNotification} />
  );
}

📖 API Reference

InAppNotificationProvider

The provider component that manages notification state and renders notifications.

Props

| Prop | Type | Default | Description | | ------------------- | ---------------------- | ----------- | --------------------------------------------------- | | notificationStyle | StyleProp<ViewStyle> | undefined | Global style applied to all notifications | | avoidStatusBar | boolean | undefined | Whether to avoid the status bar area (Android only) | | width | number | 85 | Default notification width (percentage) | | height | number | undefined | Default notification height (percentage) | | titleWidth | number | 70 | Default title width (percentage) | | messageWidth | number | 70 | Default message width (percentage) | | contentWidth | number | undefined | Default content container width (percentage) | | imageSize | number | 12 | Default image size (percentage) | | borderRadius | number | 5 | Default border radius (percentage) |

Example

<InAppNotificationProvider
  avoidStatusBar={true}
  width={90}
  borderRadius={8}
  notificationStyle={{
    backgroundColor: '#1a1a1a',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  }}
>
  {children}
</InAppNotificationProvider>

useInAppNotification Hook

Returns methods to control notifications.

Return Value

{
  addNotification: (notificationItem: Omit<NotificationItem, 'id'>, id?: string) => void;
  updateNotification: (notificationId: string, notificationItem: Omit<NotificationItem, 'id'>) => void;
  removeNotification: (notificationId: string) => void;
}

Methods

addNotification(notificationItem, id?)

Adds a new notification to the queue.

  • notificationItem: The notification configuration (without id)
  • id (optional): Custom notification ID for tracking
updateNotification(notificationId, notificationItem)

Updates an existing notification.

  • notificationId: The ID of the notification to update
  • notificationItem: The new notification configuration
removeNotification(notificationId)

Removes a notification from the queue.

  • notificationId: The ID of the notification to remove

NotificationItem Type

The core notification configuration object.

type NotificationItem = {
  id: string; // Auto-generated if not provided
  style?: StyleProp<ViewStyle>; // Individual notification style
  content: NotificationContent; // Notification content
  duration?: number; // Display duration in milliseconds (default: 5000)
  activeOpacity?: number; // Touch opacity (default: 0.8)
  onPress?: (content: NotificationContent, dismiss: () => void) => void;
  onNotificationLeave?: () => void;
  onNotificationEnter?: () => void;
};

NotificationContent Type

Defines the notification content, which can be either data-driven or a custom component.

Data Type Notification

{
  type: 'data';
  payload: {
    title?: string;
    message?: string;
    Icon?: JSX.Element;
    image?: ImageSourcePropType;
    imageStyle?: StyleProp<ImageStyle>;
    titleStyle?: StyleProp<TextStyle>;
    messageStyle?: StyleProp<TextStyle>;
    contentContainerStyle?: StyleProp<ViewStyle>;
    // Size overrides
    width?: number;
    height?: number;
    titleWidth?: number;
    messageWidth?: number;
    contentWidth?: number;
    imageSize?: number;
    borderRadius?: number;
  };
}

Component Type Notification

{
  type: 'component';
  payload: React.ReactNode;
}

💡 Usage Examples

Basic Text Notification

const { addNotification } = useInAppNotification();

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'New Message',
      message: 'You have received a new message from John.',
    },
  },
  duration: 4000,
});

Notification with Image

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'Profile Updated',
      message: 'Your profile picture has been changed.',
      image: require('./assets/avatar.png'),
      imageStyle: {
        borderRadius: 25,
      },
    },
  },
});

Notification with Custom Icon

import { Icon } from 'your-icon-library';

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'Success!',
      message: 'Operation completed successfully.',
      Icon: <Icon name="check-circle" size={40} color="#4CAF50" />,
    },
  },
});

Custom Styled Notification

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'Error',
      message: 'Something went wrong. Please try again.',
      titleStyle: {
        color: '#F44336',
        fontWeight: 'bold',
        fontSize: 16,
      },
      messageStyle: {
        color: '#666',
        fontSize: 14,
      },
      contentContainerStyle: {
        backgroundColor: '#FFEBEE',
        padding: 16,
      },
    },
  },
  style: {
    borderLeftWidth: 4,
    borderLeftColor: '#F44336',
  },
  duration: 5000,
});

Interactive Notification

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'New Friend Request',
      message: 'John Doe wants to connect with you.',
      image: { uri: 'https://example.com/avatar.jpg' },
    },
  },
  onPress: (content, dismiss) => {
    // Navigate to friend request screen
    navigation.navigate('FriendRequests');
    dismiss(); // Dismiss the notification
  },
  activeOpacity: 0.7,
});

Custom Component Notification

const CustomNotification = () => (
  <View style={{ padding: 20, backgroundColor: '#2196F3', borderRadius: 10 }}>
    <Text style={{ color: 'white', fontSize: 18, fontWeight: 'bold' }}>
      Custom Design
    </Text>
    <Text style={{ color: 'white', fontSize: 14 }}>
      You have full control over the UI!
    </Text>
  </View>
);

addNotification({
  content: {
    type: 'component',
    payload: <CustomNotification />,
  },
  duration: 3000,
});

Notification with Lifecycle Callbacks

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'Download Complete',
      message: 'Your file has been downloaded successfully.',
    },
  },
  onNotificationEnter: () => {
    console.log('Notification appeared');
    // Play sound, haptic feedback, etc.
  },
  onNotificationLeave: () => {
    console.log('Notification dismissed');
    // Cleanup, analytics, etc.
  },
});

Updating a Notification

const { addNotification, updateNotification } = useInAppNotification();

// Add with custom ID
const notificationId = 'download-progress';

addNotification(
  {
    content: {
      type: 'data',
      payload: {
        title: 'Downloading...',
        message: '0% complete',
      },
    },
    duration: 10000,
  },
  notificationId
);

// Later, update the progress
updateNotification(notificationId, {
  content: {
    type: 'data',
    payload: {
      title: 'Downloading...',
      message: '50% complete',
    },
  },
  duration: 10000,
});

Notification Queue Example

// Notifications will automatically stack and animate nicely
const showMultiple = () => {
  addNotification({
    content: {
      type: 'data',
      payload: { title: 'First', message: 'First notification' },
    },
  });

  addNotification({
    content: {
      type: 'data',
      payload: { title: 'Second', message: 'Second notification' },
    },
  });

  addNotification({
    content: {
      type: 'data',
      payload: { title: 'Third', message: 'Third notification' },
    },
  });
};

🎨 Styling Guide

Global Styling

Use the provider props to set default styles for all notifications:

<InAppNotificationProvider
  width={88}
  borderRadius={12}
  notificationStyle={{
    backgroundColor: '#ffffff',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.3,
    shadowRadius: 4.65,
    elevation: 8,
  }}
>

Per-Notification Styling

Override global styles for individual notifications:

addNotification({
  content: {
    type: 'data',
    payload: {
      title: 'Special Notification',
      message: 'This one looks different!',
      titleStyle: { color: '#9C27B0' },
      messageStyle: { color: '#555' },
      contentContainerStyle: {
        backgroundColor: '#F3E5F5',
      },
    },
  },
  style: {
    width: '95%',
    borderRadius: 15,
  },
});

Theme System Example

// Define your notification themes
const notificationThemes = {
  success: {
    style: {
      borderLeftWidth: 4,
      borderLeftColor: '#4CAF50',
    },
    payload: {
      titleStyle: { color: '#2E7D32' },
      contentContainerStyle: { backgroundColor: '#E8F5E9' },
    },
  },
  error: {
    style: {
      borderLeftWidth: 4,
      borderLeftColor: '#F44336',
    },
    payload: {
      titleStyle: { color: '#C62828' },
      contentContainerStyle: { backgroundColor: '#FFEBEE' },
    },
  },
  info: {
    style: {
      borderLeftWidth: 4,
      borderLeftColor: '#2196F3',
    },
    payload: {
      titleStyle: { color: '#1565C0' },
      contentContainerStyle: { backgroundColor: '#E3F2FD' },
    },
  },
};

// Use the themes
const showSuccess = (title: string, message: string) => {
  addNotification({
    content: {
      type: 'data',
      payload: {
        title,
        message,
        ...notificationThemes.success.payload,
      },
    },
    style: notificationThemes.success.style,
  });
};

🔧 Advanced Configuration

Responsive Sizing

All size values are percentages relative to screen dimensions:

<InAppNotificationProvider
  width={85}           // 85% of screen width
  height={10}          // 10% of screen height
  imageSize={15}       // 15% of screen width
  titleWidth={70}      // 70% of notification width
  messageWidth={70}    // 70% of notification width
  borderRadius={6}     // 6% of shortest screen dimension
/>

Image Handling

The package automatically detects and uses the best image component available:

  1. expo-image (preferred)
  2. react-native-fast-image
  3. Standard Image (fallback)

No additional configuration needed!

Android Status Bar

On Android, you can control whether notifications avoid the status bar:

<InAppNotificationProvider avoidStatusBar={true}>

Performance Optimization

For best performance:

  1. Memoize custom components used in notifications
  2. Use callback refs for lifecycle hooks
  3. Limit the number of simultaneous notifications (3-5 recommended)
  4. Use appropriate durations (3000-5000ms for most cases)

🐛 Troubleshooting

Notifications Not Showing

  1. Ensure InAppNotificationProvider wraps your component tree
  2. Verify GestureHandlerRootView wraps your app
  3. Check that Reanimated is properly configured

Animation Issues

  1. Make sure Reanimated Babel plugin is last in your plugins array
  2. Clear Metro cache: npx react-native start --reset-cache
  3. Rebuild your app after adding the Babel plugin

TypeScript Errors

Ensure you have the correct peer dependency versions installed:

npm install --save-dev @types/react @types/react-native

Custom Components Not Rendering

When using type: 'component', ensure your component:

  • Is wrapped in a View with proper dimensions
  • Handles its own styling completely
  • Doesn't rely on parent context that might not be available

📝 TypeScript Support

Full TypeScript definitions are included. Import types as needed:

import type {
  NotificationItem,
  NotificationContent,
  NotificationDataPayload,
  NotificationSizeOptions,
  InAppNotificationProviderProps,
} from '@shaquillehinds/react-native-in-app-notification';

🤝 Contributing

Contributions are welcome! Please read our Contributing Guide and Code of Conduct.

📄 License

MIT © Shaquille Hinds

🔗 Links

🙏 Dependencies

This package is built on top of excellent open-source projects:


Made with ❤️ by Shaquille Hinds