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

irismail

v1.0.0

Published

Simple email sending service and beautiful OTP input components for React

Readme

IrisMail

npm version npm downloads License: ISC TypeScript

A lightweight npm package for sending emails via Gmail and beautiful OTP input components for React.

Features

  • Email Service: Simple Gmail-based email sending with minimal configuration
  • OTP Input: Beautiful, accessible OTP input components with copy-paste support
  • Themeable: Dark and light themes built-in
  • Flexible: Multiple sizes (sm/md/lg) and customizable styles via classNames API
  • Composable: Build custom layouts with InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator
  • Easy to Use: Minimal API surface - just a few props to get started
  • Type-Safe: Built with TypeScript
  • Zero Config: Just add your Gmail credentials - no SMTP configuration needed

Installation

IrisMail works with all major package managers. No additional configuration is required.

npm install irismail
pnpm add irismail
yarn add irismail
bun add irismail

Package Exports

| Import | Description | |--------|-------------| | irismail/server | Email service (IrisMail class and types) | | irismail/react | OTP components (OTP, InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator) | | irismail | All exports (server + react + utils) |

Email Service

Send emails with just your Gmail credentials:

import { IrisMail } from 'irismail/server';

const mail = new IrisMail({
  auth: {
    user: process.env.GMAIL_USER!,
    pass: process.env.GMAIL_APP_PASSWORD!,
  },
});

await mail.sendMail({
  from: process.env.GMAIL_USER!,
  to: '[email protected]',
  subject: 'Hello!',
  html: '<h1>Welcome</h1><p>Thanks for signing up!</p>',
});

Note: You'll need to generate a Gmail App Password for authentication.

OTP Input Component

Basic Usage

'use client';

import { useState } from 'react';
import { OTP } from 'irismail/react';

export function VerifyForm() {
  const [code, setCode] = useState('');

  return (
    <OTP
      value={code}
      onChange={setCode}
      onComplete={(value) => verify(value)}
    />
  );
}

With Error State

<OTP
  value={code}
  onChange={setCode}
  error={isInvalid}
/>

Custom Length

<OTP length={4} value={code} onChange={setCode} />

Themes

Use the theme prop to switch between dark and light color schemes:

// Dark theme (default)
<OTP theme="dark" value={code} onChange={setCode} />

// Light theme - for light backgrounds
<OTP theme="light" value={code} onChange={setCode} />

Sizes

Use the slotSize prop to change the slot dimensions:

<OTP slotSize="sm" value={code} onChange={setCode} />
<OTP slotSize="md" value={code} onChange={setCode} />  // default
<OTP slotSize="lg" value={code} onChange={setCode} />

Separator & Grouping

Add visual separators and control grouping:

// With separator (auto groups: 3-3 for 6 digits)
<OTP separator value={code} onChange={setCode} />

// Custom group size (2-2-2 for 6 digits)
<OTP separator groupSize={2} value={code} onChange={setCode} />

// Stripe-style (3-3 for 6 digits)
<OTP length={6} separator groupSize={3} value={code} onChange={setCode} />

Custom Styling (classNames API)

Use the classNames prop to customize individual parts:

<OTP
  value={code}
  onChange={setCode}
  separator
  groupSize={3}
  classNames={{
    slot: "rounded-none first:rounded-l-md last:rounded-r-md",
    slotActive: "ring-2 ring-indigo-500 ring-offset-1 ring-offset-zinc-900",
    separator: "mx-4",
    separatorLine: "bg-indigo-500 w-4 h-0.5",
    caret: "bg-indigo-400",
  }}
/>

Composition Pattern

For custom layouts, use the composition components:

import {
  InputOTP,
  InputOTPGroup,
  InputOTPSlot,
  InputOTPSeparator,
} from 'irismail/react';

<InputOTP maxLength={6} value={code} onChange={setCode}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
    <InputOTPSlot index={2} />
  </InputOTPGroup>
  <InputOTPSeparator />
  <InputOTPGroup>
    <InputOTPSlot index={3} />
    <InputOTPSlot index={4} />
    <InputOTPSlot index={5} />
  </InputOTPGroup>
</InputOTP>

InputOTP and composition components support the same styling props: theme, slotSize, error, and classNames.

OTP Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | length | number | 6 | Number of OTP digits | | value | string | — | Controlled input value | | onChange | (value: string) => void | — | Called when value changes | | onComplete | (value: string) => void | — | Called when all digits entered | | theme | "dark" | "light" | "dark" | Color theme | | slotSize | "sm" | "md" | "lg" | "md" | Size of the input slots | | separator | boolean | false | Show separator between groups | | groupSize | number | length / 2 | Number of slots per group when separator is enabled | | disabled | boolean | false | Disable the input | | error | boolean | false | Show error styling | | autoFocus | boolean | false | Auto focus first slot | | name | string | — | Name attribute for forms | | className | string | — | Container className | | classNames | OTPClassNames | — | Styles API for fine-grained customization | | pattern | string | "^[0-9]*$" | Regex pattern to match input against |

ClassNames API

The classNames prop accepts an object with these keys for custom styling:

| Key | Description | |-----|-------------| | root | Root container element | | group | Group wrapper containing slots | | slot | Individual digit slot (base state) | | slotFilled | Slot when it contains a digit | | slotActive | Slot when focused/active | | slotError | Slot in error state | | separator | Separator container | | separatorLine | The separator dash/line element | | caret | Blinking caret cursor |

Works with both the OTP component and the composition components (InputOTP, etc.). OTP components work best with Tailwind CSS; use these class names to override or extend the default styles.

Documentation

For full documentation and interactive examples, run the docs site:

npm run site

Contributing

Contributions are welcome.

  1. Clone and install

    git clone https://github.com/nitin-1926/irismail.git
    cd irismail
    npm install
  2. Build the package

    npm run build
  3. Develop with watch mode

    npm run dev
  4. Run the documentation site

    npm run site

    Then open http://localhost:3000.

  5. Submit changes: Open a pull request with a clear description of the change. Ensure the build passes (npm run build) and the package works with the docs site.

License

ISC