README.md

March 3, 2026 ยท View on GitHub

Input OTP Native

Input OTP Native ๐Ÿ”

โœจ One time passcode Input For React Native/Expo. Unstyled and fully customizable. โœจ

Test status version downloads license Star on GitHub


Features

  • ๐Ÿ“ฑ Built specifically for React Native/Expo
  • ๐ŸŽจ Fully customizable styling with render props ( supports nativewind )
  • ๐Ÿ“‹ Four copy paste styles (Apple, Stripe, Revolt, Dashed)
  • ๐Ÿงช 100% test coverage
  • ๐Ÿ”„ Easily animated with react-native-reanimated
  • ๐ŸŒ Web support with using otp-input
## npm
npm install input-otp-native

## yarn
yarn add input-otp-native

#pnpm
pnpm add input-otp-native

Documentation

API Reference

OTPInput Props

PropTypeDefaultDescription
maxLengthnumberRequiredNumber of OTP digits
render(props: RenderProps) => ReactNodeRequiredRender function for OTP slots
valuestringundefinedControlled value of the input
onChange(value: string) => voidundefinedCallback when value changes
onComplete(value: string) => voidundefinedCallback when all digits are filled
containerStyleViewStyleundefinedStyle for the container
patternstringundefinedRegex pattern for input validation
textAlign'left' | 'center' | 'right''left'Text alignment within input
pasteTransformer(pasted: string) => stringundefinedTransform pasted text

RenderProps

PropTypeDescription
slotsSlotProps[]Array of slot objects to render
isFocusedbooleanWhether the input is focused

SlotProps

PropTypeDescription
charstring | nullCharacter in the slot
isActivebooleanWhether the slot is active
hasFakeCaretbooleanWhether to show fake caret
placeholderCharstring | nullPlaceholder character
focus() => voidFocuses the input at this slot's position, suppressing iOS clear behavior

Each slot exposes a focus() method โ€” no ref required. Pass it to onPress on a wrapping Pressable to let users tap any slot and resume typing from there:

<OTPInput
  maxLength={6}
  render={({ slots }) => (
    <View style={{ flexDirection: 'row', gap: 8 }}>
      {slots.map((slot, index) => (
        <Pressable key={index} onPress={slot.focus}>
          <Slot {...slot} />
        </Pressable>
      ))}
    </View>
  )}
/>

OTPInputRef

Use a ref to call imperative methods on the input:

const ref = useRef<OTPInputRef>(null);
<OTPInput ref={ref} ... />
MethodDescription
focus()Focus the input
blur()Blur the input
clear()Clear all digits
setValue(value: string)Set the current value programmatically
focusSlot(index: number)Truncate the value to index characters and focus โ€” making slot index the new active slot

Web support

The library is mainly inspired by otp-input and has a similar API, so we recommend using it on the web.

We can easily create the same component for web and create a new file for it (example/src/examples/apple.web.tsx)

Contributing

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

License

MIT


Credits