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

indian-validators

v1.0.0

Published

Zero-dependency, fully-typed validators for Indian identifiers — PAN, Aadhaar, GST, IFSC, PIN, Phone, UPI

Readme

indian-validators

npm version bundle size tests license

Zero-dependency, fully-typed validators for Indian identifiers — PAN, Aadhaar, GST, IFSC, PIN Code, Phone, UPI.

No network calls. No external dependencies. Works in Node.js, browsers, and any TypeScript/JavaScript project.


Install

npm install indian-validators
# or
yarn add indian-validators
# or
pnpm add indian-validators

Quick Start

import {
  validatePan,
  validateAadhaar,
  validateGst,
  validateIfsc,
  validatePincode,
  validatePhone,
  validateUpi,
} from "indian-validators";

validatePan("ABCPD1234E");
// { valid: true, type: "individual" }

validatePhone("+919876543210");
// { valid: true, normalized: "9876543210", e164: "+919876543210", operator: "Airtel" }

validateUpi("someone@okicici");
// { valid: true, identifier: "someone", handle: "okicici", provider: "Google Pay (ICICI)" }

API

All validators return an object with valid: boolean. On failure, an error string explains what went wrong. On success, additional parsed fields are returned.


validatePan(pan: string): PanResult

Validates a PAN (Permanent Account Number) card.

Format: AAAAA9999A — 5 letters, 4 digits, 1 letter. The 4th character encodes the taxpayer type.

validatePan("ABCPD1234E")
// { valid: true, type: "individual" }

validatePan("AABCT1332Q")
// { valid: true, type: "company" }

validatePan("ABCD123")
// { valid: false, error: "PAN must be exactly 10 characters" }

PAN types: individual | company | huf | firm | aop | trust | boi | local_authority | artificial_juridical | government


validateAadhaar(aadhaar: string): AadhaarResult

Validates an Aadhaar number including the Verhoeff checksum algorithm used by UIDAI.

Accepts plain 12-digit strings, or space/hyphen-separated formats.

⚠️ This validates format only. Never store or log Aadhaar numbers in your application.

validateAadhaar("234123412346")
// { valid: true }

validateAadhaar("2341 2341 2346")
// { valid: true }

validateAadhaar("034123412346")
// { valid: false, error: "Aadhaar cannot start with 0 or 1" }

validateAadhaar("234123412347")
// { valid: false, error: "Invalid Aadhaar: checksum mismatch" }

validateGst(gstin: string): GstResult

Validates a GSTIN (Goods and Services Tax Identification Number) including state code lookup and mod-36 checksum.

Format: 22AAAAA0000A1Z5 — 2-digit state code + 10-char PAN + entity number + Z + check digit.

validateGst("22AAAAA0000A1Z5")
// {
//   valid: true,
//   stateCode: "22",
//   state: "Chhattisgarh",
//   pan: "AAAAA0000A",
//   entityNumber: "1"
// }

validateGst("22AAAAA0000A1Z9")
// { valid: false, error: "Invalid GSTIN: checksum mismatch (expected 5)" }

validateIfsc(ifsc: string): IfscResult

Validates an IFSC (Indian Financial System Code).

Format: SBIN0001234 — 4-letter bank code + 0 + 6-char branch code.

validateIfsc("SBIN0001234")
// {
//   valid: true,
//   bankCode: "SBIN",
//   bankName: "State Bank of India",
//   branchCode: "001234"
// }

validateIfsc("HDFC0001234")
// { valid: true, bankCode: "HDFC", bankName: "HDFC Bank", branchCode: "001234" }

validateIfsc("SBIN1001234")
// { valid: false, error: "Invalid IFSC format..." }

validatePincode(pincode: string | number): PincodeResult

Validates an Indian PIN code (Postal Index Number).

Format: 6 digits, first digit 1–9 (never 0).

validatePincode("400001")
// { valid: true, zone: "Western Zone (Maharashtra, Goa, MP, Chhattisgarh)" }

validatePincode(110001)
// { valid: true, zone: "Northern Zone (Delhi, Haryana, Punjab, HP, J&K)" }

validatePincode("000001")
// { valid: false, error: "PIN code cannot start with 0" }

validatePhone(phone: string): PhoneResult

Validates an Indian mobile number. Accepts multiple common formats.

Accepted formats: 9876543210, +919876543210, 919876543210, 09876543210

validatePhone("+919876543210")
// { valid: true, normalized: "9876543210", e164: "+919876543210", operator: "Airtel" }

validatePhone("6012345678")
// { valid: true, normalized: "6012345678", e164: "+916012345678", operator: "Jio" }

validatePhone("1234567890")
// { valid: false, error: "Indian mobile numbers must start with 6, 7, 8, or 9" }

validateUpi(upi: string): UpiResult

Validates a UPI Virtual Payment Address (VPA).

Format: identifier@handle — e.g. name@paytm, 9876543210@okicici

validateUpi("someone@okicici")
// { valid: true, identifier: "someone", handle: "okicici", provider: "Google Pay (ICICI)" }

validateUpi("9876543210@paytm")
// { valid: true, identifier: "9876543210", handle: "paytm", provider: "Paytm" }

validateUpi("ranjit.kumar@ybl")
// { valid: true, identifier: "ranjit.kumar", handle: "ybl", provider: "PhonePe (Yes Bank)" }

validateUpi("missingat")
// { valid: false, error: 'UPI ID must contain "@" symbol' }

TypeScript Types

All return types are exported:

import type {
  PanResult, PanType,
  AadhaarResult,
  GstResult,
  IfscResult,
  PincodeResult,
  PhoneResult,
  UpiResult,
} from "indian-validators";

Why This Library

Every Indian startup's dev team writes these validators from scratch. This library aims to be the definitive, well-tested, zero-dependency solution so you never have to write ^[A-Z]{5}[0-9]{4}[A-Z]{1}$ again.

  • ✅ Validates format and checksums (Aadhaar Verhoeff, GST mod-36)
  • ✅ Returns structured data, not just true/false
  • ✅ Full TypeScript types, zero any
  • ✅ Zero runtime dependencies
  • ✅ Works in Node.js, browsers, and edge runtimes
  • ✅ ~4KB minzipped

Contributing

PRs welcome! If you find an edge case or want to add a new validator (Vehicle Registration, Voter ID, Driving Licence, etc.), open an issue first.

git clone https://github.com/rohitjazz/indian-validators
cd indian-validators
npm install
npm test

License

MIT © Ranjit Singh