npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-nat-otp

v1.0.3

Published

Customizable React OTP input with 12 GSAP-powered animations (6 success & 6 error animations).

Readme

react-nat-otp

npm version license bundle size TypeScript

A modern, accessible React OTP input component powered by 12 GSAP micro-animations (6 celebratory success effects and 6 dynamic error effects).


🌟 Demo & Playground

Experience all animations in action:


✨ Features

  • 🎭 12 GSAP-Powered Animations: 6 rich success effects and 6 intuitive error feedback animations.
  • 🎯 Seamless Verification Flow: Built-in async/sync backend validation with loading state and custom status messages.
  • 📱 Robust Input Handling: Smooth single-digit typing, overwrite on focus, backspace navigation, arrow key traversal, and multi-digit paste support.
  • 🎨 Deeply Customizable: Control box sizes, gap spacing, corner radius, font sizing, and custom CSS/Tailwind classes.
  • 🌐 Framework Agnostic Styles: Works seamlessly with Tailwind CSS or with standard CSS via the included stylesheet.
  • ♿ Accessible: Built with keyboard navigation, ARIA attributes, and screen reader announcements.
  • 🚀 Production-Ready: Fully typed with TypeScript, delivering lightweight ESM and CommonJS bundles.

📦 Installation

npm install react-nat-otp gsap

or with yarn / pnpm / bun:

yarn add react-nat-otp gsap
# or
pnpm add react-nat-otp gsap
# or
bun add react-nat-otp gsap

Note: React 18+ is required. Import the stylesheet once in your app entry point (e.g. main.tsx, App.tsx, or layout.tsx):

import 'react-nat-otp/styles.css';

🚀 Quick Start

'use client';

import React from 'react';
import { OTPInput } from 'react-nat-otp';
import 'react-nat-otp/styles.css';

export default function OtpVerificationPage() {
  const verifyOtp = async (code: string) => {
    // Simulate real backend API verification
    await new Promise((resolve) => setTimeout(resolve, 600));
    return code === '12345678';
  };

  return (
    <div style={{ display: 'flex', justifyContent: 'center', padding: '40px' }}>
      <OTPInput
        length={8}
        boxSize={44}
        gap={8}
        radius={8}
        successAnimation="pill"
        errorAnimation="shake"
        onComplete={(otp) => console.log('OTP entered:', otp)}
        onVerify={async (otp) => {
          return await verifyOtp(otp);
        }}
      />
    </div>
  );
}

🎭 Animations Catalog

🟢 Success Animations (successAnimation)

| Animation | Description | | :--- | :--- | | checkmark | Boxes merge into the center and reveal an animated emerald checkmark (✓). | | pill | Individual boxes smoothly fuse together into a single, cohesive capsule pill button. | | flip | Staggered 3D domino card flips with elastic bounce settle. | | burst (Default) | Boxes merge into center with a vibrant 360° multi-colored confetti particle blast. | | wave | Harmonious liquid sine-wave ripple jump flowing from left to right. | | jackpot | Casino-style 3D slot machine vertical tumble roll and celebratory glow. |

🔴 Error Animations (errorAnimation)

| Animation | Description | | :--- | :--- | | shake (Default) | Boxes converge into center with an animated red cross (✕) and snappy headshake vibration. | | domino | Domino tile collapse effect that falls outward and rebounds back into place. | | glitch | Rapid high-frequency crisp haptic vibration with red glow. | | squash | Bouncy liquid jelly squash-and-stretch drop physics. | | tornado | 180° alternating cyclone vortex spin from center outward. | | heartbeat | Urgent double-thump emergency alarm pulse and scale flash. |


⚙️ Props Reference

| Prop | Type | Default | Description | | :--- | :--- | :--- | :--- | | length | number | 6 | Total number of OTP digit boxes. | | boxSize | number | 44 | Box width and height in pixels. | | gap | number | 8 | Spacing between input boxes in pixels. | | radius | number | 8 | Corner border radius in pixels. | | fontSize | number | derived | Custom font size in pixels (defaults to Math.round(boxSize * 0.42)). | | successAnimation | SuccessAnimationType | 'burst' | 'checkmark' \| 'pill' \| 'flip' \| 'burst' \| 'wave' \| 'jackpot' | | errorAnimation | ErrorAnimationType | 'shake' | 'shake' \| 'domino' \| 'glitch' \| 'squash' \| 'tornado' \| 'heartbeat' | | onComplete | (code: string) => void | — | Callback fired synchronously when all digits are entered. | | onVerify | (code: string) => Promise<boolean \| { success: boolean; message?: string }> | — | Async/sync verification function that communicates with your backend API. | | autoFocus | boolean | true | Automatically focuses the first input box on component mount. | | className | string | '' | Custom CSS class names applied to the container. | | style | React.CSSProperties | — | Custom inline style object applied to the container. |


💡 Advanced Usage

Custom Response Messages from Backend

You can return custom status feedback messages directly from your onVerify function:

<OTPInput
  length={6}
  onVerify={async (code) => {
    const res = await fetch('/api/verify-otp', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ otp: code }),
    });

    const data = await res.json();

    // Return an object with custom status message
    return {
      success: res.ok && data.success,
      message: data.message || (res.ok ? 'Code accepted!' : 'Invalid code!'),
    };
  }}
/>

🛠️ Development & Contributing

To build and test the package locally:

# Clone the repository
git clone https://github.com/betopia/react-nat-otp.git
cd react-nat-otp

# Install dependencies
npm install

# Run type check
npm run typecheck

# Build ESM, CJS, and DTS bundles
npm run build

📄 License

MIT © Betopia