Charcoal UI

OTP Input

One-time-code input with a blinking caret, digits that pop in, paste support and autofill.

  • Category: Inputs
  • Licence: Free, MIT
  • Built with: React 19, Tailwind CSS 4, Motion
  • Dependencies: motion, clsx, tailwind-merge

Examples

OTP Input

API reference

PropTypeDefaultDescription
lengthnumber6
valuestring—Controlled value.
defaultValuestring—Initial value when uncontrolled.
onValueChange(value: string) => void—
onComplete(code: string) => void—
errorboolean—Shakes and tints the slots.
disabledboolean—

About OTP Input

OTP Input is the six-box code field from a two-factor screen, done properly: digits pop in as you type, the caret blinks in the active box, pasting a whole code fills every box, and mobile autofill from an SMS just works.

OTP Input is an input component for React 19, styled with Tailwind CSS 4 and animated with Motion. It drops into Next.js, Vite, Remix or Astro through the shadcn CLI as a single file you own.

When to use OTP Input

  • Two-factor authentication and login codes.
  • Email or phone verification steps in sign-up.
  • Payment confirmation codes.
  • Any short numeric or alphanumeric code entry.

How it works

It is one hidden input with autocomplete one-time-code behind visual slots, which is why paste and SMS autofill work everywhere. The slots are drawn from the value; an error prop shakes and tints them, and onComplete fires when the last digit lands.

It is a real form control: it has an accessible name, works with the keyboard alone, shows a visible focus ring and announces its state to screen readers. With prefers-reduced-motion on, it holds still or settles instantly instead of animating.

Customizing OTP Input

Every prop is documented in the API reference above with its type and default. The ones you will reach for first are listed here.

The Customize panel next to the preview lets you change length, disabled live, and the Code tab updates to match, so the snippet you copy already carries your values.

  • length (number, default 6).
  • value (string): Controlled value.
  • defaultValue (string): Initial value when uncontrolled.
  • error (boolean): Shakes and tints the slots.
  • disabled (boolean).

Goes well with OTP Input

These inputs pieces share its tokens and motion language, so they sit together on one page without clashing.

  • Range Slider: Six animated React range sliders on one accessible core: inline, tick, fluid, wave, bubble and ruler
  • Button: An animated React button with six variants, spring press feedback and a width-stable loading state
  • Switch: An animated React toggle switch whose thumb stretches when pressed, like a real switch
  • Checkbox: An animated React checkbox: the check draws itself in, the box pops, indeterminate morphs to a dash
  • Radio Group: An animated React radio group with roving focus and a highlight that glides between card options

Install OTP Input

npx shadcn@latest add https://charcoalui.com/r/otp-input.json

OTP Input is free and MIT licensed. The command copies otp-input.tsx into components/ui and installs clsx, tailwind-merge; you can also copy the source from the Code tab by hand.

It pairs well with Split Flap, a Pro piece: Airport departure board: every cell flips through the drum until it lands on its letter.

Frequently asked questions

Can I change the number of digits?
Yes. The length prop sets how many slots there are, from four to eight is typical, and onComplete fires once that many characters are entered.
How do I install OTP Input?
Run npx shadcn@latest add https://charcoalui.com/r/otp-input.json. The shadcn CLI copies otp-input.tsx into components/ui and installs motion, clsx, tailwind-merge. You can also copy the source from this page by hand.
Is OTP Input free for commercial use?
Yes. OTP Input is MIT licensed: use it in any personal or commercial project and change it however you like.
Does OTP Input work with Next.js?
Yes. It is a client component for React 19 styled with Tailwind CSS 4, so it works in the Next.js App Router and Pages Router, Vite, Remix and Astro.
Can an AI coding agent install OTP Input?
Yes. Connect the Charcoal UI MCP server (https://charcoalui.com/mcp) to Claude Code, Cursor or any MCP client; get_component returns OTP Input's props and source and get_install_command returns the exact command.

OTP Input as Markdown · llms.txt