# OTP input

> One-time code boxes that handle paste and autofill, and shake on a wrong code.

Component · Free · https://lodeui.com/components/otp-input

## When to use

- Email or SMS verification codes and 2FA.

## When not to use

- Passwords or anything longer than ~8 characters.

## Installation

```bash
npx shadcn@latest add https://lodeui.com/r/otp-input.json
```

npm dependencies: motion

## Usage

```tsx title="example.tsx"
import { OtpInput } from "@/components/ui/otp-input";

export function Verify({ onCode, error }: { onCode: (code: string) => void; error: boolean }) {
  return <OtpInput onComplete={onCode} error={error} />;
}
```

## API reference

### OtpInput

Code boxes backed by one real input, so paste and SMS autofill work.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| length | `number` | `6` | Number of boxes. |
| value / onValueChange | `string` | – | Controlled value; non-digits are stripped. |
| onComplete | `(code) => void` | – | Called when every box is filled. |
| error | `boolean` | – | Shakes and marks invalid. |

## Keyboard interactions

| Keys | Action |
| --- | --- |
| 0–9 | Type a digit |
| Backspace | Delete |
| ⌘V / Ctrl+V | Paste a whole code |

## Accessibility

- One input with inputMode="numeric" and autocomplete="one-time-code".
- aria-invalid on error.

## Motion

- The row shakes on error (400ms).

## Responsive behavior

- Boxes are 40px; six fit at 320px.

## Performance

- No timers.

## Notes for AI

- Change the key to reset after an error.

## Related

- [Input](https://lodeui.com/components/input) — Text, search, password and URL inputs with icons, clear button and a labelled Field wrapper.
- [Button](https://lodeui.com/components/button) — A clear, responsive action with quiet secondary states.
