Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
OTPInput
✓ import { OTPInput } from 'input-otp'
✗ const OTPInput = require('input-otp')
OTPInput is a named export. When used in frameworks like Next.js App Router, the file containing this component or its parent must include `'use client'` at the top.
SlotProps
✓ import type { SlotProps } from 'input-otp'
✗ import { SlotProps } from 'input-otp'
This is a TypeScript type used for defining the props passed to custom slot components in the render prop. Use `import type` for clarity and stricter type checking.
OTPInputProps
✓ import type { OTPInputProps } from 'input-otp'
✗ import { OTPInputProps } from 'input-otp'
This is a TypeScript type defining all available props for the main OTPInput component. Use `import type` for clarity and stricter type checking.
Demonstrates how to render a custom styled 6-digit OTP input using the `render` prop, including a blinking caret and a dash separator, leveraging common Tailwind CSS utilities for visual presentation.
'use client'
import { OTPInput, SlotProps } from 'input-otp'
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
import type { ClassValue } from 'clsx'
// Small utility to merge class names (commonly used with Tailwind CSS).
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
// Custom Slot component to render individual OTP digits.
function Slot(props: SlotProps) {
return (
<div
className={cn(
'relative w-10 h-14 text-[2rem]',
'flex items-center justify-center',
'transition-all duration-300',
'border-border border-y border-r first:border-l first:rounded-l-md last:rounded-r-md',
'group-hover:border-accent-foreground/20 group-focus-within:border-accent-foreground/20',
'outline outline-0 outline-accent-foreground/20',
{ 'outline-4 outline-accent-foreground': props.isActive }
)}
>
<div className="group-has-[input[data-input-otp-placeholder-shown]]:opacity-20">
{props.char ?? props.placeholderChar}
</div>
{props.hasFakeCaret && <FakeCaret />}
</div>
)
}
// Emulates a blinking caret for visual feedback.
function FakeCaret() {
return (
<div className="absolute pointer-events-none inset-0 flex items-center justify-center animate-caret-blink">
<div className="w-px h-8 bg-white" />
</div>
)
}
// A visual separator, inspired by Stripe's MFA input.
function FakeDash() {
return (
<div className="flex w-10 justify-center items-center">
<div className="w-3 h-1 rounded-full bg-border" />
</div>
)
}
// Example form component using OTPInput.
export default function MyOTPForm() {
return (
<form className="flex gap-2"> {/* Added a wrapper form for context */}
<OTPInput
maxLength={6}
containerClassName="group flex items-center has-[:disabled]:opacity-30"
render={({ slots }) => (
<>
<div className="flex">
{slots.slice(0, 3).map((slot, idx) => (
<Slot key={idx} {...slot} />
))}
</div>
<FakeDash />
<div className="flex">
{slots.slice(3).map((slot, idx) => (
<Slot key={idx} {...slot} />
))}
</div>
</>
)}
/>
</form>
)
}
Errors
Common errors & fixes
Error: You're importing a component that needs 'useState'. It only works in a Client Component - add the 'use client' directive at the top of the file to turn it into one.
Attempting to use `OTPInput` in a Server Component context (e.g., Next.js App Router) without marking it as a Client Component.
fixAdd `'use client'` as the very first line of code in the file where the `OTPInput` component is imported or rendered.
Argument of type '{ slots: SlotProps[]; }' is not assignable to parameter of type 'ReactNode'.
Incorrect type inference or usage of the `render` prop, typically when TypeScript is not correctly understanding the expected return type or arguments of the `render` function.
fixEnsure the `render` prop explicitly returns JSX elements (`React.ReactNode`) and correctly destructures the `{ slots }` argument, using `SlotProps` for type safety if defining custom slot components. Verify your TypeScript configuration is properly set up for JSX. Audit
Dependencies
reactrequiredCore React library for component functionality.
react-domrequiredRequired for rendering React components to the DOM.