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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-nitro-notification

v0.7.0

Published

Remote push notifications (APNs) via Nitro Modules

Downloads

268

Readme

react-native-nitro-notification

A high-performance React Native remote push notification library built on NitroModules.

Platform support: iOS only. Android support is not yet implemented.

Installation

pnpm add react-native-nitro-notification
npx pod-install

iOS setup

The library needs to receive the APNs device token from your app delegate. Add the following to your AppDelegate:

import NitroNotification

func application(
  _ application: UIApplication,
  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
  NotificationCenter.default.post(
    name: NitroNotificationTokenNotification,
    object: nil,
    userInfo: [NitroNotificationTokenKey: deviceToken]
  )
}

No other app delegate changes are required. The library registers itself as a UNUserNotificationCenterDelegate automatically at load time.

Usage

Request permissions

import { Notifications } from 'react-native-nitro-notification';

const status = await Notifications.requestPermissions({
  alert: true,
  sound: true,
  badge: true,
});
// status: 'granted' | 'denied' | 'undetermined' | 'provisional'

Get current permission status

const status = await Notifications.getPermissionStatus();

Get the APNs push token

requestPermissions automatically registers for remote notifications on success, so the token is available immediately after a 'granted' or 'provisional' result.

const token = await Notifications.getDevicePushToken();

Unregister from remote notifications

await Notifications.unregisterForNotifications();

Listen for events

// Token refreshed
const sub = Notifications.addOnTokenRefreshed((token) => {
  console.log('New token:', token);
});

// Notification tapped
const sub = Notifications.addOnNotificationTapped((response) => {
  console.log('Tapped:', response.notification.title);
  console.log('Action:', response.actionIdentifier);
});

// Clean up
sub.remove();

Handle taps when the app was closed

addOnNotificationTapped only fires for listeners that exist when the tap arrives. When a tap launches the app from a killed state, your JS listener is not registered yet, so the event is lost. The library keeps the most recent tap natively so you can read it on startup:

// Run once the navigation is ready
const response = Notifications.getLastNotificationResponse();
if (response) {
  navigateTo(response);
  Notifications.clearLastNotificationResponse();
}

Only the most recent tap is stored. Call clearLastNotificationResponse after handling it, otherwise the same tap is returned again the next time you read it (for example after a JS reload).

On Android, getLastNotificationResponse currently always returns undefined.

Handle foreground notifications

By default, foreground notifications are presented with alert, badge, and sound. Use setNotificationHandler to control presentation per notification:

Notifications.setNotificationHandler(async (notification) => {
  console.log('Received in foreground:', notification.title);
  return { alert: true, badge: true, sound: false };
});

// Clear the handler
Notifications.setNotificationHandler(undefined);

The handler has a default timeout of 5000 ms. If it rejects or times out, the notification falls back to showing alert, badge, and sound.

// Custom timeout
Notifications.setNotificationHandler(async (notification) => {
  return { alert: true, badge: false, sound: true };
}, 3000);

Notification categories and actions

Register categories to attach action buttons (and inline text replies) to notifications. A notification uses a category when its push payload has a matching categoryIdentifier.

await Notifications.setNotificationCategories([
  {
    identifier: 'message',
    actions: [
      {
        identifier: 'reply',
        buttonTitle: 'Reply',
        textInput: { submitButtonTitle: 'Send', placeholder: 'Write a reply' },
      },
      {
        identifier: 'delete',
        buttonTitle: 'Delete',
        options: { isDestructive: true, opensAppToForeground: false },
      },
    ],
  },
]);

Notifications.addOnNotificationTapped((response) => {
  if (response.actionIdentifier === 'reply') {
    console.log('Reply text:', response.userText);
  }
});

setNotificationCategories replaces the full set of registered categories. Calling it again removes any category that is not in the new array, so always pass every category your app needs.

On Android this method currently rejects with an UnsupportedOperationException.

API

Notifications

| Method | Description | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | requestPermissions(options?) | Prompts the user for notification permissions. Returns the resulting PermissionStatus. On success, also calls registerForRemoteNotifications() so the push token is immediately available. | | getPermissionStatus() | Returns the current PermissionStatus without prompting. | | getDevicePushToken() | Registers for remote notifications and resolves with the APNs device token as a hex string. | | unregisterForNotifications() | Unregisters from remote notifications on the device. | | setNotificationHandler(handler, timeoutMs?) | Sets a callback invoked when a notification arrives while the app is in the foreground. The handler returns NotificationPresentationOptions to control how the notification is shown. Pass undefined to clear the handler. | | setNotificationCategories(categories) | Registers the notification categories and their actions. Replaces all previously registered categories. Rejects on Android. | | addOnTokenRefreshed(listener) | Subscribes to push token refresh events. Returns a ListenerSubscription. | | addOnNotificationTapped(listener) | Subscribes to notification tap events. Returns a ListenerSubscription. | | getLastNotificationResponse() | Synchronously returns the most recent NotificationResponse, or undefined if there is none. Use it on startup to recover a tap that launched the app from a killed state. Always undefined on Android. | | clearLastNotificationResponse() | Clears the stored response so it is not returned again. |

PermissionStatus

| Value | Description | | ---------------- | ---------------------------------------------------------------------------------------------------------- | | 'granted' | The user has authorized notifications. | | 'denied' | The user has denied notifications. | | 'undetermined' | The user has not yet been asked. | | 'provisional' | Provisional authorization (iOS) -- notifications deliver silently to Notification Center without a prompt. |

RequestPermissionsOptions

All fields are iOS-specific. On Android, this object is accepted but ignored.

| Property | Type | Default | Description | | --------------------------------- | ---------- | ------- | ---------------------------------------------------------------------------------- | | alert | boolean? | true | Show notification banners and Notification Center entries. | | sound | boolean? | true | Play a sound when a notification is delivered. | | badge | boolean? | true | Update the app icon badge number. | | carPlay | boolean? | false | Display notifications in CarPlay. | | criticalAlert | boolean? | false | Play sound even when muted or Do Not Disturb is on. Requires an Apple entitlement. | | providesAppNotificationSettings | boolean? | false | Show a link to your in-app notification settings from the system settings page. | | provisional | boolean? | false | Request provisional authorization -- no prompt shown to the user. |

NotificationPayload

| Property | Type | Description | | -------- | ------------------------- | ------------------------------------ | | title | string? | Notification title. | | body | string? | Notification body. | | data | Record<string, string>? | Custom key-value payload. | | badge | number? | Badge count included in the payload. |

NotificationResponse

Received in addOnNotificationTapped callbacks and returned by getLastNotificationResponse.

| Property | Type | Description | | ------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------- | | notification | NotificationPayload | The notification that was tapped. | | actionIdentifier | string | The identifier of the action that was invoked (e.g. UNNotificationDefaultActionIdentifier for a plain tap). | | userText | string? | Text typed by the user when the action has a textInput. Undefined otherwise or when the field is empty. |

NotificationCategory

| Property | Type | Description | | ------------ | ------------------------------ | ------------------------------------------------------------ | | identifier | string | Matches the categoryIdentifier field in the push payload. | | actions | NotificationAction[] | Actions shown on notifications of this category. | | options | NotificationCategoryOptions? | iOS-specific category options. |

NotificationCategoryOptions

All fields are iOS only.

| Property | Type | Description | | ----------------------- | ----------- | ------------------------------------------------------------------------ | | previewPlaceholder | string? | Body placeholder shown when the user has hidden previews. | | intentIdentifiers | string[]? | Siri intent class identifiers associated with the category. | | categorySummaryFormat | string? | Format string for the grouped notification summary. | | customDismissAction | boolean? | Notify the app when the user explicitly dismisses the notification. | | allowInCarPlay | boolean? | Allow the actions to appear in CarPlay. | | showTitle | boolean? | Show the title even when the user has hidden previews. | | showSubtitle | boolean? | Show the subtitle even when the user has hidden previews. |

NotificationAction

| Property | Type | Description | | ------------- | ---------------------------- | -------------------------------------------------------------- | | identifier | string | Delivered back in NotificationResponse.actionIdentifier. | | buttonTitle | string | Label shown on the action button. | | textInput | NotificationTextInput? | When present, the action becomes an inline text reply field. | | options | NotificationActionOptions? | Action behavior options. |

NotificationActionOptions

| Property | Type | Default | Description | | -------------------------- | ---------- | ------- | ---------------------------------------------------------------- | | isDestructive | boolean? | false | Render the button in a destructive style. iOS only. | | isAuthenticationRequired | boolean? | false | Require device authentication before the action fires. iOS only. | | opensAppToForeground | boolean? | true | Bring the app to the foreground when the action is triggered. |

NotificationTextInput

| Property | Type | Description | | ------------------- | -------- | ----------------------------------------------- | | submitButtonTitle | string | Title of the submit button. iOS only. | | placeholder | string | Placeholder shown before the user starts typing. |

NotificationPresentationOptions

Returned by the NotificationHandler to control foreground presentation.

| Property | Type | Description | | -------- | --------- | ----------------------------- | | alert | boolean | Show the notification banner. | | badge | boolean | Update the app icon badge. | | sound | boolean | Play the notification sound. |

NotificationHandler

type NotificationHandler = (notification: NotificationPayload) => Promise<NotificationPresentationOptions>;

ListenerSubscription

interface ListenerSubscription {
  remove: () => void;
}

License

MIT