react-native-otp-entry vs react-otp-input
Implementing OTP Input Fields in React and React Native
react-native-otp-entryreact-otp-input

Implementing OTP Input Fields in React and React Native

react-native-otp-entry and react-otp-input are UI components designed to handle One-Time Password (OTP) or verification code entry in React applications. react-otp-input is primarily built for React web applications, offering a customizable input field that splits characters into separate boxes. react-native-otp-entry is tailored for React Native mobile environments, focusing on native keyboard handling, auto-fill support, and mobile-specific UX patterns. Both aim to simplify the implementation of secure code entry but target different rendering platforms.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-native-otp-entry041928.6 kB1410 months agoMIT
react-otp-input0697142 kB462 years agoMIT

React Native OTP Entry vs React OTP Input: Platform Specifics and Implementation

Both react-native-otp-entry and react-otp-input solve the same user problem: entering a short verification code securely. However, they operate in fundamentally different environments. One targets the mobile native ecosystem, while the other targets the web DOM. Choosing the wrong one for your platform will lead to broken builds or poor user experience. Let's compare how they handle input, styling, and platform features.

📱 Platform Target: Native Mobile vs Web DOM

react-native-otp-entry is built exclusively for React Native.

  • It uses native TextInput components under the hood.
  • It relies on mobile-specific props like keyboardType and autoFill hints.
  • It will not work in a standard React web project.
// react-native-otp-entry: Native implementation
import { OTPEntry } from 'react-native-otp-entry';

export default function App() {
  return (
    <OTPEntry
      totalDigits={6}
      onTextChange={(text) => console.log(text)}
    />
  );
}

react-otp-input is built for React web applications.

  • It renders standard HTML <input> elements.
  • It manages focus and cursor position within the browser DOM.
  • It is not designed for React Native's native component tree.
// react-otp-input: Web implementation
import OtpInput from 'react-otp-input';

export default function App() {
  return (
    <OtpInput
      numInputs={6}
      onChange={(text) => console.log(text)}
      renderInput={(props) => <input {...props} />}
    />
  );
}

⌨️ Input Handling and Keyboard Types

react-native-otp-entry configures the mobile keyboard directly.

  • You can specify keyboardType='numeric' to show the number pad.
  • It handles focus movement between boxes automatically when a digit is typed.
  • It supports secure text entry masking if needed.
// react-native-otp-entry: Keyboard config
<OTPEntry
  totalDigits={6}
  keyboardType="number-pad"
  secureTextEntry={false}
  onTextChange={(code) => setCode(code)}
/>

react-otp-input relies on HTML input attributes.

  • You must pass type="tel" or inputMode="numeric" for mobile browsers.
  • Focus management is handled via JavaScript refs within the component.
  • It supports custom rendering of each input box.
// react-otp-input: Input mode config
<OtpInput
  numInputs={6}
  inputType="tel"
  inputMode="numeric"
  onChange={(code) => setCode(code)}
  renderInput={(props) => <input {...props} />}
/>

🎨 Styling and Customization

react-native-otp-entry uses React Native style objects.

  • Styles are applied using the style prop accepting a StyleSheet.
  • You can customize the container and individual digit boxes.
  • It supports theme props for active and filled states.
// react-native-otp-entry: Styling
<OTPEntry
  totalDigits={6}
  styles={{
    digitBox: { borderWidth: 1, borderColor: '#ccc' },
    filledBox: { borderColor: '#000' }
  }}
  onTextChange={(text) => setText(text)}
/>

react-otp-input uses CSS classes or inline styles.

  • You pass containerStyle or inputStyle props.
  • It supports CSS-in-JS or standard class names.
  • You have full control over the DOM structure via renderInput.
// react-otp-input: Styling
<OtpInput
  numInputs={6}
  inputStyle={{ border: '1px solid #ccc' }}
  containerStyle={{ display: 'flex', gap: '10px' }}
  onChange={(text) => setText(text)}
  renderInput={(props) => <input {...props} />}
/>

📋 Clipboard and Auto-Fill Support

react-native-otp-entry integrates with OS auto-fill.

  • It supports SMS Retriever API on Android.
  • It works with iOS security code auto-fill.
  • Paste functionality is handled natively by the TextInput.
// react-native-otp-entry: Auto-fill hints
<OTPEntry
  totalDigits={6}
  textContentType="oneTimeCode"
  onTextChange={(text) => setText(text)}
/>

react-otp-input handles clipboard via browser events.

  • It listens for paste events on the input fields.
  • It supports autoComplete="one-time-code" for browser support.
  • Auto-fill depends on browser and OS integration with the web view.
// react-otp-input: Auto-complete
<OtpInput
  numInputs={6}
  autoComplete="one-time-code"
  onChange={(text) => setText(text)}
  renderInput={(props) => <input {...props} />}
/>

🌱 When Not to Use These

These packages are specialized for OTP flows. Consider alternatives when:

  • You need a general purpose form library: Use formik or react-hook-form with standard inputs.
  • You are building a React Native Web app: Ensure the package you pick supports the target platform, or use a universal library like react-native-otp-text-input.
  • Your design requirements are unique: If the OTP UI deviates heavily from standard boxes, building a custom component might be cleaner than overriding library styles.

📌 Summary Table

Featurereact-native-otp-entryreact-otp-input
Platform📱 React Native (iOS/Android)🌐 React Web (DOM)
Underlying ElementNative TextInputHTML <input>
StylingReact Native StyleSheetCSS / Inline Styles
Auto-FillNative OS SMS/Code FillBrowser autoComplete
KeyboardkeyboardType propinputMode / type props
Paste SupportNative ClipboardJS Paste Event

💡 Final Recommendation

Think in terms of target environment first:

  • Building a mobile app? → Use react-native-otp-entry. It leverages native capabilities for SMS auto-fill and keyboard management that web components cannot access.
  • Building a website? → Use react-otp-input. It is optimized for browser behavior, clipboard pasting, and DOM focus management.

Critical Note: Do not attempt to use react-otp-input in a React Native project. It relies on DOM APIs that do not exist in the native runtime. Conversely, react-native-otp-entry will not render in a web browser. Always match the package to your rendering engine.

How to Choose: react-native-otp-entry vs react-otp-input

  • react-native-otp-entry:

    Choose react-native-otp-entry if you are building a mobile application using React Native. It is optimized for touch interfaces, supports native auto-fill APIs on iOS and Android, and handles soft keyboard interactions correctly. This package is essential when you need the OTP field to integrate seamlessly with mobile OS features like SMS retreival.

  • react-otp-input:

    Choose react-otp-input if you are developing a web application using React.js. It provides robust support for desktop and mobile browsers, handling clipboard pasting and character separation effectively in a DOM environment. This package is the standard choice for web-based login flows where React Native specific native modules are not available.

README for react-native-otp-entry

react-native-otp-entry

npm version npm install size cov License

react-native-otp-entry is a simple and highly customizable React Native component for entering OTP (One-Time Password) on iOS, Android, and Web. It provides an intuitive and user-friendly interface for inputting one-time passwords in your React Native applications.

Looking for a Phone Number input component? Check out react-native-phone-entry - a simple and fully modifiable Phone Number Input Component for React Native that provides an intuitive interface for entering and validating international phone numbers.

Demo

Features

  • Simple and easy-to-use OTP input component.
  • Highly customizable appearance and styling.
  • Supports autofill
  • Effortlessly integrates with React Native, Expo, and React Native Web platforms.
  • Fully typed with TypeScript.
  • Fully covered with unit tests.
  • Paste functionality.

Demo

Try out React Native OTP Entry in action on Snack Expo:

Snack Expo App

or https://snack.expo.dev/@anday013/demo-react-native-otp-entry

Installation

Install react-native-otp-entry using npm or yarn:

npm install react-native-otp-entry

# or

yarn add react-native-otp-entry

Usage

  1. Import the OtpInput component from react-native-otp-entry:

    import { OtpInput } from "react-native-otp-entry";
    
  2. Render the OtpInput component in your screen/component:

    <OtpInput numberOfDigits={6} onTextChange={(text) => console.log(text)} />
    
  3. Customize the styling as per your requirements:

    <OtpInput
      numberOfDigits={6}
      focusColor="green"
      autoFocus={false}
      hideStick={true}
      placeholder="******"
      blurOnFilled={true}
      disabled={false}
      type="numeric"
      secureTextEntry={false}
      focusStickBlinkingDuration={500}
      onFocus={() => console.log("Focused")}
      onBlur={() => console.log("Blurred")}
      onTextChange={(text) => console.log(text)}
      onFilled={(text) => console.log(`OTP is ${text}`)}
      textInputProps={{
        accessibilityLabel: "One-Time Password",
      }}
      textProps={{
        accessibilityRole: "text",
        accessibilityLabel: "OTP digit",
        allowFontScaling: false,
      }}
      theme={{
        containerStyle: styles.container,
        pinCodeContainerStyle: styles.pinCodeContainer,
        pinCodeTextStyle: styles.pinCodeText,
        focusStickStyle: styles.focusStick,
        focusedPinCodeContainerStyle: styles.activePinCodeContainer,
        placeholderTextStyle: styles.placeholderText,
        filledPinCodeContainerStyle: styles.filledPinCodeContainer,
        disabledPinCodeContainerStyle: styles.disabledPinCodeContainer,
      }}
    />
    

Props

The react-native-otp-entry component accepts the following props:

PropTypeDescription
numberOfDigitsnumberThe number of digits to be displayed in the OTP entry.
themeThemeCustom styles for each element. (See below)
textInputPropsTextInputPropsExtra props passed to underlying hidden TextInput (see: https://reactnative.dev/docs/textinput)
textPropsTextPropsProps passed to the Text component that renders each digit (see: https://reactnative.dev/docs/text)
autoFocusbooleanDefault: true. Sets autofocus.
focusColorColorValueThe color of the input field border and stick when it is focused.
placeholderstringPlaceholder value to the input.
onTextChange(text: string) => voidA callback function is invoked when the OTP text changes. It receives the updated text as an argument.
onFilled(text: string) => voidA callback function is invoked when the OTP input is fully filled. It receives a full otp code as an argument.
blurOnFilledbooleanDefault: false. Blurs (unfocuses) the input when the OTP input is fully filled.
hideStickbooleanDefault: false. Hides cursor of the focused input.
focusStickBlinkingDurationnumberThe duration (in milliseconds) for the focus stick to blink.
disabledbooleanDefault: false. Disables the input
type'alpha' | 'numeric' | 'alphanumeric'The type of input. 'alpha': letters only, 'numeric': numbers only, 'alphanumeric': letters or numbers.
secureTextEntrybooleanDefault: false. Obscures the text entered so that sensitive text like PIN stay secure.
onFocus() => voidA callback function is invoked when the OTP input is focused.
onBlur() => voidA callback function is invoked when the OTP input is blurred.
ThemeTypeDescription
containerStyleViewStyleCustom styles for the root View.
pinCodeContainerStyleViewStyleCustom styles for the container that wraps each individual digit in the OTP entry.
pinCodeTextStyleTextStyleCustom styles for the text within each individual digit in the OTP entry.
placeholderTextStyleTextStyleCustom styles for the placeholder text within each individual digit in the OTP entry.
focusStickStyleViewStyleCustom styles for the focus stick, which indicates the focused input field.
focusedPinCodeContainerStyleViewStyleCustom styles for the input field when it is focused.
filledPinCodeContainerStyleViewStyleCustom styles for the input field when it has a value.
disabledPinCodeContainerStyleViewStyleCustom styles for the input field when it is disabled.

Note: The ViewStyle and TextStyle types are imported from react-native and represent the style objects used in React Native for views and text, respectively.

Tip: If you have difficulties while applying gap or in any other style property to set a suitable space between the OTP input containers, please set the width in containerStyle to 'auto' or undefined, as it is been set to '100%' by default.

Theme

Ref

The react-native-otp-entry component exposes these functions with ref:

PropTypeDescription
clear() => void;Clears the value of the OTP input.
focus() => void;Focus of the OTP input.
blur() => void;Blurs the OTP input.
setValue(value: string) => void;Sets the value of the OTP input.

License

This project is licensed under the MIT License.

Contributing

Contributions are welcome! Please feel free to open issues or submit pull requests.

If you find a bug or have any feature requests, please open an issue :)

Support Me

If you find this project helpful and want to support my work, consider buying me a coffee! ☕

Buy Me a Coffee