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-otp-input-pro

v1.0.0

Published

A production-ready, fully customizable OTP input component for React Native with animations, themes, and advanced features

Readme

react-native-otp-input-pro

A quick preview of react-native-otp-input-pro showcasing built-in animations, multiple themes, secure input, SMS autofill, customizable styling, error & success states, and powerful ref methods. Designed to provide a smooth, production-ready OTP verification experience for both Android and iOS.


🎥 Demo


Features

  • Any Length — 4, 5, 6, 8 digits, or any custom count
  • Smart Auto-fill — Android SMS autofill and iOS OTP autofill out of the box
  • Built-in Animations — Scale, Bounce, Shake, Fade, Slide, Pulse, Focus Glow
  • 10 Themes — Light, Dark, Glass, Minimal, Material, Filled, Outlined, Rounded, Square, Neumorphism
  • Ref Methods — Programmatic focus, clear, shake, success, error, and more
  • RTL Support — Automatic Arabic and Hebrew support
  • Accessible — Full screen reader support
  • Zero Dependencies — Pure JavaScript, no Expo required

Installation

npm install react-native-otp-input-pro
# or
yarn add react-native-otp-input-pro

Quick Start

import React, { useState } from "react";
import { View, Text, SafeAreaView } from "react-native";
import { OTPInput } from "react-native-otp-input-pro";

const App = () => {
  const [otp, setOtp] = useState("");

  return (
    <SafeAreaView style={{ flex: 1, justifyContent: "center", padding: 20 }}>
      <OTPInput
        value={otp}
        onChange={setOtp}
        onComplete={(value) => console.log("OTP complete:", value)}
        length={6}
        theme="light"
        animation="bounce"
        autoFocus
      />
    </SafeAreaView>
  );
};

export default App;

Props

Core

| Prop | Type | Default | Description | | ----------------- | ------------------------- | -------------- | ----------------------------------- | | value | string | '' | Current OTP value | | onChange | (value: string) => void | — | Called on every input change | | onComplete | (value: string) => void | — | Called when all digits are filled | | length | number | 6 | Number of OTP digits | | secureTextEntry | boolean | false | Mask input characters | | keyboardType | string | 'number-pad' | Keyboard type | | editable | boolean | true | Allow editing | | autoFocus | boolean | false | Auto-focus the first input on mount | | placeholder | string | '●' | Placeholder character | | disabled | boolean | false | Disable all inputs | | loading | boolean | false | Show loading state |

Appearance

| Prop | Type | Default | Description | | -------------------- | -------- | ----------- | --------------------------------------------------------------------------------------------------------- | | theme | string | 'light' | light, dark, glass, minimal, material, filled, outlined, rounded, square, neumorphism | | inputWidth | number | 50 | Width of each input cell | | inputHeight | number | 60 | Height of each input cell | | borderRadius | number | 8 | Border radius | | borderWidth | number | 1 | Border width | | borderColor | string | '#ccc' | Default border color | | focusedBorderColor | string | '#007AFF' | Border color when focused | | errorBorderColor | string | '#FF3B30' | Border color on error | | successBorderColor | string | '#34C759' | Border color on success | | backgroundColor | string | '#fff' | Cell background color | | fontSize | number | 20 | Font size | | fontWeight | string | '400' | Font weight | | gap | number | 8 | Gap between cells |

State & Validation

| Prop | Type | Default | Description | | -------------- | --------- | ------- | -------------------------------- | | error | boolean | false | Show error state | | success | boolean | false | Show success state | | errorMessage | string | '' | Error message shown below inputs |

Animation

| Prop | Type | Default | Description | | ------------------- | --------- | -------- | -------------------------------------------------------------------------- | | animation | string | 'none' | scale, bounce, shake, fade, slide, pulse, focus-glow, none | | animationDuration | number | 300 | Duration in milliseconds | | animationEnabled | boolean | true | Enable or disable animations |

Auto-fill & Accessibility

| Prop | Type | Default | Description | | -------------------- | --------- | --------------- | ------------------------------- | | textContentType | string | 'oneTimeCode' | iOS autofill hint | | autoComplete | string | 'sms-otp' | Android autofill hint | | accessibilityLabel | string | 'OTP input' | Screen reader label | | hapticFeedback | boolean | false | Enable haptic feedback on input |


Ref Methods

const otpRef = useRef(null);

<OTPInput ref={otpRef} length={6} />;

| Method | Description | | ------------------ | ------------------------------ | | focus() | Focus the first input | | blur() | Blur the active input | | clear() | Clear all inputs | | setValue(value) | Set value programmatically | | getValue() | Get current value | | shake() | Trigger shake animation | | success() | Trigger success animation | | error() | Trigger error animation | | focusCell(index) | Focus a specific cell by index |


Examples

Error State with Shake

<OTPInput
  length={6}
  error={error}
  errorMessage="Invalid OTP. Please try again."
  animation="shake"
  onChange={(value) => {
    if (value.length === 6) validateOTP(value);
  }}
/>

Ref-controlled Validation

const otpRef = useRef(null);

const handleSubmit = () => {
  const value = otpRef.current?.getValue();
  if (value === expectedOTP) {
    otpRef.current?.success();
  } else {
    otpRef.current?.shake();
    otpRef.current?.error();
  }
};

<OTPInput ref={otpRef} length={6} />;

Custom Styling

<OTPInput
  length={6}
  inputWidth={55}
  inputHeight={65}
  borderRadius={12}
  borderColor="#6200EE"
  focusedBorderColor="#BB86FC"
  backgroundColor="#F5F5F5"
  fontSize={24}
  fontWeight="600"
  gap={12}
/>

SMS Auto-fill

<OTPInput length={6} textContentType="oneTimeCode" autoComplete="sms-otp" />

Firebase Phone Auth

const confirmCode = async () => {
  try {
    const credential = auth.PhoneAuthProvider.credential(verificationId, otp);
    await auth().signInWithCredential(credential);
  } catch (error) {
    otpRef.current?.shake();
  }
};

<OTPInput
  value={otp}
  onChange={setOtp}
  onComplete={confirmCode}
  length={6}
  ref={otpRef}
/>;

Troubleshooting

Input not focusing on Android — Set autoFocus={true} and ensure no other view is intercepting touches.

SMS autofill not working — Confirm both textContentType="oneTimeCode" (iOS) and autoComplete="sms-otp" (Android) are set.

Performance issues — Set animationEnabled={false} to disable animations entirely.


Requirements

  • React Native 0.70+
  • No additional native setup required

License

This project is under the MIT license.


Author

Built with ❤️ by Nascenture.

  • 🌐 Website: https://www.nascenture.com
  • 📱 React Native Development Services: https://www.nascenture.com/react-native-app-development/