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
Maintainers
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-proQuick 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/
