OTP Input

A verification code field with one slot per digit: a focus ring that slides between slots, digits that roll into place, paste and SMS autofill support, a shake on wrong codes and a drawn check on success.

Preview

OTP Input preview width

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @karaui/otp-input
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

length?
number

Number of slots. Default 6.

6
value?
string
—
defaultValue?
string
onChange?
((value: string) => void)
—
onComplete?
((value: string) => void)

Fires once every slot is filled.

—
label?
string

Optional label rendered above the slots.

—
hint?
string

Helper text shown below the slots while idle.

—
successMessage?
string

Message shown below the slots when status is "success".

—
errorMessage?
string

Message shown below the slots when status is "error".

—
status?
"idle" | "success" | "error"

External validation feedback. "error" shakes, "success" draws a check.

idle
mask?
boolean

Render dots instead of the typed digits.

false
disabled?
boolean
false
autoFocus?
boolean
false
aria-label?
string

Accessible label for the underlying input.

One-time passcode
className?
string
—

Keep in mind

Some components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.

Updated