A react-otp-input alternative with the whole verify step
react-otp-input draws the code boxes and leaves the rest to you. The Step-Up OTP Gate is the full verification card: six cells, paste and one-time-code autofill, a spinning check, a resend timer and the page behind it unlocking.

By buying you agree to the Terms.
- Download right after paying
- Use it in client projects
- Won't run on the listed stack? We fix it or refund you
Ready forCursorv0Lovableshadcn CLI
Use it in Next.js
"use client";
// Before:
// const [otp, setOtp] = useState("");
// <OtpInput value={otp} onChange={setOtp} numInputs={6} renderInput={(props) => <input {...props} />} />
// plus your own submit button, error text and resend link
import { useRouter } from "next/navigation";
import { StepUpGate } from "@/components/StepUpGate";
import { checkCode, sendCode } from "./actions";
export default function VerifyPage() {
const router = useRouter();
return (
<StepUpGate
length={6} // was numInputs
title="Check your phone"
description="Enter the 6-digit code we just sent."
onVerify={async (code) => (await checkCode(code)).ok} // false shows "Try again" and clears the cells
onResend={() => void sendCode()}
resendSeconds={30}
onVerified={() => router.push("/dashboard")}
>
{/* whatever should sit blurred behind the code card */}
<div className="grid min-h-dvh place-items-center bg-[#0b0c10] text-white/40">Your account</div>
</StepUpGate>
);
}"use server";
// Your backend's check. Supabase, Clerk and Firebase each have a guide on this site.
const API = process.env.AUTH_API_URL!;
export async function checkCode(code: string): Promise<{ ok: boolean }> {
const res = await fetch(`${API}/verify`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code }),
});
return { ok: res.ok };
}
export async function sendCode(): Promise<void> {
await fetch(`${API}/send-code`, { method: "POST" });
}Good to know
- react-otp-input 3.1.1 is the latest release, published December 12, 2023, and the repo's last push was July 2024. Its peer range is react >=16.8.6, so it installs in a React 19 app without flags. npm counted 214,039 downloads in the last week of October 2026.
- If all you need is a code field inside your own form, a free input is the right tool. react-otp-input still works for that, and input-otp (the library shadcn/ui's Input OTP is built on) supports React 19 and had a release in August 2026.
- The OTP Gate is a different size of thing: the dialog, the frosted page behind it, the error shake, the success state and the resend countdown come with it. You write onVerify and nothing else.
- Paste works on any cell: it keeps the digits, fills the row and submits when the code is complete. The first cell has autocomplete="one-time-code", so iOS and Android can offer the code from Messages.
- The cells take digits only. For letter-and-number codes, a free input like input-otp with a pattern fits better.
What each react-otp-input prop becomes
- numInputs: length (6 by default).
- value and onChange: the gate keeps the digits itself. You get the full code once, in onVerify.
- renderInput, inputStyle and containerStyle: the cells are drawn for you. Their look lives in the component's CSS file, which you can edit.
- shouldAutoFocus: the first cell takes focus when the card opens.
- onPaste: built in. A pasted code fills every cell.
Moving off react-code-input
- react-code-input 3.10.1 is its last release, published March 26, 2021, and it still gets about 17,000 downloads a week.
- Its package.json lists react ^16.3.2 as a regular dependency. In a React 19 app npm 10 installs a separate React 16.14 just for it (we checked). Its fields and onChange map the same way as react-otp-input's: fields becomes length, and onChange plus your submit button becomes onVerify.
Moving off react-verification-code-input
- react-verification-code-input 1.2.9 is its last release, published December 12, 2020, with about 7,000 downloads a week.
- Its peer range stops at React 17, so npm 10 stops with ERESOLVE in a React 18 or 19 app unless you pass --legacy-peer-deps. Its fields prop becomes length, onComplete becomes onVerify, and the loading state it asked you to manage is the gate's spinning arcs.
Install
- Copy from the zipPut
react/src/components + react/src/dataintosrc/, thennpm uninstall react-otp-input && npm i framer-motion. - Or ask your AIPaste PROMPT.md into Cursor, Lovable or v0.
Props
- onVerify
- check the code, resolve true to unlock
- length
- number of cells
- onResend / resendSeconds
- resend link and its countdown
- autofillCode
- the code the From Messages chip offers
- children
- the page that stays frosted
How qodesign compares
- qodesign vs Magic UIMagic UI is best for: landing pages built with shadcn/ui.
- qodesign vs Aceternity UIAceternity UI is best for: teams building many marketing pages who want one big library.
All comparisons, with prices read on each library's own site.
Questions
Is react-otp-input abandoned?
We wouldn't say that. Its last release was December 2023 and it still installs in React 19. Pick it if you want a plain input you style yourself.
Does the OTP Gate work with Supabase, Clerk or Firebase codes?
Yes. Call their verify function inside onVerify and return true when it passes. We have a guide for each.
Does the OTP gate work in Next.js?
Yes, as a client component. Keep "use client" at the top of the file that renders it, as in the snippet above. App Router and Pages Router both work.
Can Cursor or v0 add it for me?
Yes. Each download has a PROMPT.md. Paste it into Cursor, Lovable, v0 or Claude Code and it fits the piece into your app.
Can I use it in client work?
Yes, in personal and client projects. You can't resell the code itself as a kit.