
Most OTP UIs just… sit there.
So I tried something different, an animated OTP field where every digit pulses, glows, and moves like it’s being typed in real-time. Not just functional, but playful.
Here's how it works:
1. Loop
The animation runs in a clean loop. But instead of timers or CSS tricks, I forced a remount with React:
const [animateKey, setAnimateKey] = useState(0);
setInterval(() => setAnimateKey(prev => prev + 1), delay);
Each time the key changes, React resets the component - triggering the full animation again.
2. Simulated typing illusion
To make it feel like someone’s typing each digit, I used an activeIndex that increments every 400ms:
setInterval(() => setActiveIndex(prev => prev + 1), 400); It looks natural, but unlike real typing, it's perfectly timed and smooth.
3. Fade, then reset
Once the last digit appears, a delayed fade resets everything:
if (activeIndex === digits.length - 1) {
setTimeout(() => setFadeOut(true), 450);
} This gives the whole thing a loop that feels almost... organic.
4. Motion
I used motion/react for most of the effects - scale, blur, opacity, glow. This one div creates a glowing ripple:
<motion.div
animate={{
opacity: [0, 1, 0],
scale: [0.85, 1.3],
filter: 'blur(2px)',
}}
transition={{ delay: 2.25 }}
/>
5. Tracking spotlight
To make the glow follow each digit as it "types", I used layoutId:
<motion.div layoutId="glow" /> It's like a spotlight gliding from one digit to the next - super smooth with zero manual animation logic.
6. Micro-details matter
Everything was tuned:
easeInOut for pacing
spring transition with stiffness/damping for bounce
No randomness. Every detail was deliberate.
If you're building UI that needs to feel more alive, I'd recommend playing with these techniques. It's wild what a little motion and timing can do.
Try the live version here: https://forgeui.in/components/animated-otp
If you found it useful, the repo's here - would mean a lot if you gave it a ⭐:
https://github.com/AmanShakya0018/forgeui
Wrote my first article - if you have any feedback, I'd genuinely love to hear how I can improve for next time.
2
18
1