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

rn-incoming-call-nitro

v0.3.0

Published

incoming-call

Readme

react-native-incoming-call 📞

A high-performance React Native library for displaying full-screen incoming call notifications on Android, powered by Nitro Modules for fast, synchronous Native-JS communication.


Features

  • Full-Screen Incoming Call Overlay: Displays on top of the lock screen and other applications.
  • Nitro Modules: Fast and direct Native-to-JS interface.
  • Highly Configurable: Custom avatar, title, body, sound, actions text, and custom payloads.
  • Custom React Native Components: Render your own React Native view within the native incoming call activity using mainComponent.
  • Event Callbacks: Simple event listeners for call answered, declined, or timed out.

Installation

npm install react-native-incoming-call react-native-nitro-modules
# or using yarn
yarn add react-native-incoming-call react-native-nitro-modules
# or using pnpm
pnpm add react-native-incoming-call react-native-nitro-modules

[!IMPORTANT] react-native-nitro-modules is required as this library is built on top of Nitro Modules.


Android Configuration

Ensure your app requests the necessary notification permissions at runtime (especially on Android 13+). You can request POST_NOTIFICATIONS permission like this:

import { Platform, PermissionsAndroid } from 'react-native';

async function checkAndRequestPermissions() {
  if (Platform.OS === 'android' && Platform.Version >= 33) {
    const hasPermission = await PermissionsAndroid.check(
      PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
    );
    if (!hasPermission) {
      await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
      );
    }
  }
}

Usage

Here is a complete usage example showing how to initialize listeners, trigger notifications, and respond to call events:

import React, { useEffect } from 'react';
import { View, Button, Alert } from 'react-native';
import IncomingCall, { show, dismiss, on, off, backToApp } from 'react-native-incoming-call';

export default function App() {
  useEffect(() => {
    // 1. Subscribe to events
    on('answer', (payload) => {
      console.log('Call Answered! UUID:', payload.callUUID);
      Alert.alert('Call Answered', `UUID: ${payload.callUUID}`);
      
      // Bring app to foreground if needed
      backToApp();
    });

    on('endCall', (payload) => {
      console.log(`Call Ended/Declined (Action: ${payload.endAction})`);
      Alert.alert('Call Declined', `UUID: ${payload.callUUID}\nAction: ${payload.endAction}`);
    });

    return () => {
      // 2. Clean up listeners on unmount
      off('answer');
      off('endCall');
    };
  }, []);

  const triggerCall = () => {
    const callUUID = '123e4567-e89b-12d3-a456-426614174000';
    
    show(
      callUUID,
      'https://i.pravatar.cc/300', // Avatar URL (nullable)
      15000,                      // Timeout (ms) (nullable)
      {
        channelId: 'incoming_call_channel',
        channelName: 'Incoming Calls',
        notificationIcon: 'ic_launcher', // Fallback to app icon resource
        notificationTitle: 'Kiattisak Jomram',
        notificationBody: 'Incoming video call...',
        answerText: 'Accept Call',
        declineText: 'Decline',
        isVideo: true,
        notificationColor: 'colorAccent', // Resource name in colors.xml
        payload: {
          callerId: 'user_kiattisak_123',
          chatRoom: 'room_call_abc',
        },
      }
    );
  };

  const manualDismiss = () => {
    dismiss();
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="Trigger Call Overlay" onPress={triggerCall} />
      <Button title="Dismiss Notification" onPress={manualDismiss} />
    </View>
  );
}

API Reference

Methods

show(uuid, avatar, timeoutMs, options)

Displays the full-screen incoming call overlay (Android only).

  • uuid (string): Unique identifier for the call.
  • avatar (string | null): Image URL of the caller's avatar.
  • timeoutMs (number | null): Timeout in milliseconds after which the call is auto-dismissed.
  • options (IncomingCallNotificationOptions): Configuration options for the notification.

dismiss()

Manually dismisses the incoming call notification.

backToApp()

Brings the host application back to the foreground (highly useful after answering).

answer(uuid, payload?)

Simulates call acceptance programmatically, triggering the 'answer' event and dismissing the notification.

decline(uuid, payload?)

Simulates call decline programmatically, triggering the 'endCall' event and dismissing the notification.

on(event, handler)

Subscribes to native events:

  • 'answer': Fired when the call is accepted.
  • 'endCall': Fired when the call is declined, times out, or is manually dismissed.

off(event)

Unsubscribes from events.


Custom React Native UI (mainComponent)

You can fully customize the incoming call screen by registering a custom React Native component and passing its name in the options.mainComponent property.

  1. Register the component in your root index file:

    import { AppRegistry } from 'react-native';
    import CustomCallScreen from './CustomCallScreen';
    
    AppRegistry.registerComponent('CustomCallScreen', () => CustomCallScreen);
  2. Pass the registered component name to show:

    show(uuid, avatar, timeoutMs, {
      // ... other options
      mainComponent: 'CustomCallScreen',
    });
  3. Get properties in your custom screen: The component will receive the initialization properties (like uuid, notificationTitle, payload, etc.) as direct props.


Types

export interface IncomingCallNotificationOptions {
  channelId: string;
  channelName: string;
  notificationIcon: string;
  notificationTitle: string;
  notificationBody?: string | null;
  answerText: string;
  declineText: string;
  notificationColor?: string;
  notificationSound?: string;
  mainComponent?: string;
  isVideo?: boolean;
  payload?: Record<string, string>;
}

export interface CallAnswerPayload {
  callUUID: string;
  payload?: string;
}

export interface CallDeclinePayload {
  callUUID: string;
  payload?: string;
  endAction: 'ACTION_REJECTED_CALL' | 'ACTION_HIDE_CALL';
}

Contributing

Please see the Contributing Guide and Code of Conduct for details on how to get started.

License

MIT