If you are building a React, Next.js, or Node.js application for the Iranian market, you have definitely faced this challenge: Validating local data structures.
Things like National Code (Code Melli), Bank Cards, IBAN (Sheba), and Postal Codes follow complex algorithms (Luhn, ISO 7064, etc.).
Usually, developers handle this in two ways:
- Copy-pasting complex Regex patterns (Error-prone).
- Using heavy legacy libraries and manually connecting them to Zod using
refine.
Neither is ideal for a modern TypeScript stack. That's why I built zod-ir, which is now officially part of the Zod Ecosystem.
Why zod-ir? (It's not just validation)
In the latest release (v1.5.4), zod-ir shifted focus from simple validation (true/false) to Smart Data Extraction.
Imagine a form where the user enters a landline number, and you automatically detect their Province and City. Or they enter a card number, and you instantly show their Bank Logo.
1. Installation
It has zero dependencies and works as a peer dependency to Zod.
npm install zod zod-ir
2. The "Smart" Validation
Here is a real-world example of a user registration schema. Notice how clean the code is:
import { z } from "zod";
import {
zMelliCode,
zIranianMobile,
zLandline,
zCardNumber,
getLandlineInfo
} from "zod-ir";
const UserSchema = z.object({
// Validates National Code algorithm
nationalId: zMelliCode({ message: "Invalid National Code" }),
// Validates mobile prefixes (09xx)
mobile: zIranianMobile(),
// Validates Landline AND we can extract city later
phone: zLandline(),
// Validates Card Number (Luhn)
card: zCardNumber(),
});
3. Extracting Metadata (The Cool Part)
Validation is boring. Let's get data!
Feature A: Auto-detect City from Landline Don't ask users for their city if they provided a phone number.
import { getLandlineInfo } from "zod-ir";
const info = getLandlineInfo("02122334455");
console.log(info);
/* Output:
{
province: "Tehran",
city: "Tehran",
province_fa: "تهران",
city_fa: "تهران"
}
*/
Feature B: Bank Information Get the bank name, color, and logo from a card number.
import { getBankInfo } from "zod-ir";
const bank = getBankInfo("6219861012345678");
// Returns: { name: "Saman", color: "#46a0e6", logo: "..." }
4. Enterprise Ready?
Yes. I designed zod-ir to address common enterprise concerns:
Standalone Usage: You don't HAVE to use Zod. All validators (like isMelliCode) are exported as pure functions for backend use.
Tree-Shakable: If you only import isIranianMobile, the heavy bank database won't be included in your bundle.
Type-Safe: First-class TypeScript support.
Conclusion
If you are using Zod, stop writing manual regex for Iranian data. zod-ir gives you validation, transformation, and metadata extraction in one lightweight package.
Give it a try and let me know what you think!
🔗 Github: https://github.com/Reza-kh80/zod-ir
Top comments (0)