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

react-native-otp-receiver

v2.1.0

Published

Receive OTP from SMS message

Downloads

13

Readme

React Native OTP Receiver

Introduction

This package handles receiving and filling OTP from SMS message. While automatically filling the input from incoming SMS is only available for Android, we handle user pressing the autofill button on iOS keyboard.

[!IMPORTANT]
For everything to work correctly, you must send SMS in correct format and setup associated domains for iOS

| Android | iOS | | --- | --- | | Android | iOS |

Supported Versions

This libs is currently available only for the new arch.

| react-native-otp-receiver | React Native | | --- | --- | | 2.x | 0.81.4 | | 1.x | 0.76.5 | ya

Installation

yarn add @pavelgric/react-native-otp-receiver

Usage

We offer various ways of integration, what could be call low-level and high-level.

In low-level, you can use methods exported for Android to capture incoming SMS and handle iOS your own way

In high-level you use one of the prepared components (you are still responsible for rendering the UI) to easily access and render the OTP. This also has iOS integration ready.

low-level usage (Android only)

This works in two steps. You register a listener for incoming SMS and then call a method that you are expecting a SMS.

onSMSReceived

A listener for incoming SMS.

import { onSMSReceived } from 'react-native-otp-receiver';

useEffect(() => {
  const listener = onSMSReceived((sms: SMSData) => {
    // handle the oncoming sms
  });
  return () => {
    listener.remove();
  };
}, []);

the listener receives SMSData with:

{
  message?: string;
  error?: string;
}

The error could be because of timeout, see expectSMSWithOTP

expectSMSWithOTP

After calling this function, you will get notified about incoming message via the onSMSReceived listener. SMS must be correctly formatted, otherwise you won't receive it from the onSMSReceived.

There is a time window to receive the message (around 5 mins) after calling expectSMSWithOTP, after this time window passes, onSMSReceived will receive "error": "TIMEOUT", after that no message will be captured and you may want to start expectSMSWithOTP again.

After calling expectSMSWithOTP, the onSMSReceived will capture only one message. If it's not the message you expected, call expectSMSWithOTP again (but for this to happen, user would have to receive SMS containing the app hash at end, it doesn't matter if user receives any other SMS).

import { expectSMSWithOTP } from 'react-native-otp-receiver';

const res = await expectSMSWithOTP()
// the res is boolean indicating whether the listener was started successfully

requestPhoneHint

Calling this function will display prompt for user to select his own phone number.

import { requestPhoneHint } from 'react-native-otp-receiver';

const res = await requestPhoneHint()
// the res is a string containing the phoneNumber. This call may fail (e.g. user dismisses the prompt)

high-level usage

We try to assume as little as possible about what your code looks like and you should be able to configure following components to your needs.

With OTPProvider

Props

| Prop | Required | Type | Description | Default | |---|---|---|---|---| | codeInputShape | Yes | number[] | Shape for the code input. Number values in the array say how many characters are in each input cell.E.g. [1,1,1,1] is 4 cells with single char in each cell. [3, 3] are 3 chars in two cells | - | | children | No | ReactNode | The UI to render | - | | onCodeEntered | No | (data: OnCodeEnteredData) => void |Function called after user fills in the code in it's full length | - | | onSubmitCode | No | (data: OnSubmitCodeData) => void; | Function called after user fills in the code in it's full length. In this callback you should do your code validation | - | | onCodeChanges | No | (code: string) => void | Called whenever the code value changes | - | | parseSMS | No | (sms: string) => string \| null \| undefined | (Android only) Function called when user receives the SMS and expects you to return the code extracted from it | - | | expectSMSOnMount | No | boolean | Whether to automatically call expectSMSWithOTP. If not set to true, you must call expectSMSWithOTP manually | - | | value | No | string | Use to set the code input value manually | - | | parseEnteredCodeChar | No | (char: string) => string | Modify the entered char that user enters via keyboard. E.g. to capitalize it | - | | parsePastedCode | No | (code: string, codeInputShape: number[]) => string[]; | When user pastes copied (or suggested) value, here you can parse the value into input cells. E.g. to parse ABC-XYZ into ['ABC', 'XYZ'] | Function that separates string into the input shape | | validateCodeChar | No | CodeCharValidator | Each time the code changes, you can validate it. This code runs for each entered character. E.g. to only accept numbers | - | | onSMSError | No | (error: string) => void | Called when onSMSReceived returns error | - |

Example:

import { View, Button } from 'react-native';
import { OTPInputCell, OTPProvider } from 'react-native-otp-receiver';
import { useOTPContext } from '../../src/components/OTPProvider';
import styles from './styles';

const getCodeFromSMS = (sms: string) => {
  // find 6 digit code
  return sms.match(/\d{6}/)?.[0] || '';
};

export default function OTPProviderExample() {
  return (
    <OTPProvider
      codeInputShape={[1,1,1,1]} // 4 cells, each holds single char
      onCodeEntered={(code) => { /*  */ }}
      onSubmitCode={(data) => { /*   */}}
      parseSMS={getCodeFromSMS}
    >
      <CodeInputRenderer />
    </OTPProvider>
  );
}

function CodeInputRenderer() {
  const { codeInputs, isCodeValid, submitCode } = useOTPContext();

  return (
    <>
      <View style={styles.otpContainer}>
        {codeInputs.map((index) => {
          return <CodeInputComponent key={index} index={index} />;
        })}
      </View>
      <Button title="Submit" disabled={!isCodeValid} onPress={submitCode} />
    </>
  );
}

function CodeInputComponent({ index }: { index: number }) {
  return <OTPInputCell index={index} />;
}

Full example in the example app

With OTPInputHandler

Wraps the OTPProvider, some may prefer this implementation over using the provider.

Props

Provider props and:

| Prop | Required | Type | Description | |---|---|---|---| | children | Yes | (props: RenderProps) => ReactNode | The UI to render | | CodeInputCellComponent | Yes |(otpHandles: CodeInputCellComponentProps) => ReactElement | The UI component to render as an input cell |

import { View, Button, TouchableOpacity } from 'react-native';
import {
  OTPInputHandler,
  OTPInputCell,
  type CodeInputCellComponentProps,
} from 'react-native-otp-receiver';
import styles from './styles';

const getCodeFromSMS = (sms: string) => {
  return sms.match(/\d{6}/)?.[0] || '';
};

export default function OTPInputHandlerExample() {
  return (
    <OTPInputHandler
      codeInputShape={[1,1,1,1]}
      CodeInputCellComponent={CodeInputComponent}
      onCodeEntered={(code) => { /*  */ }}
      onSubmitCode={(code) => { /*  */}}
      parseSMS={getCodeFromSMS}
    >
      {({ renderOTPInput, submitCode, isValid }) => (
        <>
          <View style={styles.otpContainer}>{renderOTPInput()}</View>
          <Button title="Submit" disabled={!isValid} onPress={submitCode} />
        </>
      )}
    </OTPInputHandler>
  );
}

function CodeInputComponent(inputHandles: CodeInputCellComponentProps) {
  return <OTPInputCell {...inputHandles} />;
}

Full example in the example app

OTPInputCell

The cell that handles input of the code value. It's a wrapper around TextInput

Props

TextInput props and:

| Prop | Required | Type | Description | |---|---|---|---| | index | Yes | number | Index of the input cell |

hooks

useOTPInputCell

Returns handles to control TextInput component to capture key presses, text changes and others. Only useful if you do not use OTPInputCell component

useOTPInputCellState

Returns input cell state (like value, isFocused) and useful handles e.g. to focus input.

Generating app hash

You can get the app hash by running this command yarn react-native-otp-receiver get-app-hash. It will ask you for package name, path to your keystore file and the keystore password. This means you will have two separate app hashes, one for debug and one for production key.

Message content

Android

SMS must include app-hash at the end of the message, otherwise you won't receive it from the onSMSReceived. Other than that, the message content may be anything. It is up to you to retrieve the code value from the message content, based on what you send.

Example:

Your verification code is 123456

GawQ12fcSiS

iOS

You must set up associated domains for your app and add it to the SMS content. Than the message content must by as they say in apple docs

You can present any information at the start of the SMS message, in any format. The last line of your message needs your DNS domain name, prefixed by an at sign (@), and the one-time code, prefixed by a hash symbol (#). Separate the two components using a space. For example:

After receiving this SMS, user will will see a suggestion above their keyboard to fill this code. If you use high-level usage, pressing this code will be captured and filled automatically.

Example:

Your Example code is 123456.


@example.com #123456

iOS shortcomings

iOS doesn't have API for neither reading received SMS messages, nor to get own phone number

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library