README.md
June 2, 2026 · View on GitHub
🇮🇷 Persian Tools — The Complete TypeScript Toolkit for Persian (Farsi) Apps
A comprehensive, library-agnostic TypeScript toolkit for Persian (Farsi) text, numbers, validation, and locale utilities — runs in Node.js, Bun, and the browser.
✨ Features
Persian Tools provides 27+ utilities for Persian language processing:
🔢 Numbers & Text
- Number Conversion: Persian words ↔ numbers with fuzzy matching
- Digit Conversion: Persian ↔ Arabic ↔ English digits
- Comma Formatting: Add/remove thousands of separators
- Ordinal Numbers: Convert to/from ordinal forms
🏛️ Validation & Verification
- National ID: Validate & generate Iranian national codes (کد ملی)
- Legal ID: Validate Iranian legal entity IDs (شناسه حقوقی)
- Phone Numbers: Validate & extract operator info
- Bank Cards: Validate & identify bank names
- Extract Card Numbers: Advanced card extraction with fuzzy matching & performance optimization
- IBAN/Sheba: Validate Iranian bank account numbers
🌍 Geographic & Location
- Place Lookup: Find city/province by national ID
- Capital Cities: Get province capitals
- Coordinates: Find province from GPS coordinates
- Vehicle Plates: Parse Iranian license plates
💰 Financial & Utilities
- Bill Calculator: Parse Iranian utility bills
- Bank Detection: Identify banks from card numbers
- IBAN Tools: Complete Iranian banking support
📝 Text Processing
- Persian Validation: Detect pure Persian text
- Character Cleanup: Remove Arabic chars from Persian
- URL Fixing: Decode Persian URLs
- Half-Space: Fix Persian typography
- Time Utilities: Persian time-ago & remaining time
- Slugify: Generate URL-safe slugs from Persian text
- Text Analysis: Comprehensive Persian text analysis
🚀 Quick Start
📦 Installation
# npm
npm install @persian-tools/persian-tools
# yarn
yarn add @persian-tools/persian-tools
# pnpm
pnpm add @persian-tools/persian-tools
# bun (recommended)
bun add @persian-tools/persian-tools
💻 Usage
ES Modules (Recommended)
import { numberToWords, digitsEnToFa, verifyIranianNationalId } from '@persian-tools/persian-tools';
numberToWords(1234); // "یک هزار و دویست و سی و چهار"
digitsEnToFa("123"); // "۱۲۳"
verifyIranianNationalId("0499370899"); // true
CommonJS
const { numberToWords } = require('@persian-tools/persian-tools');
Browser CDN
<script src="https://cdn.jsdelivr.net/npm/@persian-tools/persian-tools/build/index.js"></script>
<script>
console.log(PersianTools.numberToWords(1234));
</script>
🧠 AI Agent Skills
Persian Tools ships first-class Agent Skills — focused, retrievable instruction files that let Claude Code, Cursor, Copilot, and other AI coding assistants understand the library's modules, conventions, and Persian-language nuances without you having to paste context every time.
Install the skills into your editor
# Bun
bunx skills add @persian-tools/persian-tools
# npm
npx skills add @persian-tools/persian-tools
# pnpm
pnpm dlx skills add @persian-tools/persian-tools
Each command pulls the skills/ directory into your project's local skills folder so your AI agent retrieves them automatically when you ask about a Persian Tools utility.
📖 API Reference
🔢 Number Conversion
numberToWords - Convert numbers to Persian words
import { numberToWords } from '@persian-tools/persian-tools';
// Basic usage
numberToWords(1234); // "یک هزار و دویست و سی و چهار"
numberToWords("12,345"); // "دوازده هزار و سیصد و چهل و پنج"
// Ordinal numbers
numberToWords(3, { ordinal: true }); // "سوم"
numberToWords(21, { ordinal: true }); // "بیست و یکم"
// Supports up to MAX_SAFE_INTEGER ($2^{53}$ - 1)
numberToWords(9007199254740991); // Works perfectly!
wordsToNumber - Convert Persian words to numbers
import { wordsToNumber } from '@persian-tools/persian-tools';
// Basic conversion
wordsToNumber("سه هزار دویست و دوازده"); // 3212
wordsToNumber("منفی یک میلیون"); // -1000000
// Advanced options
wordsToNumber("دوازده هزار", {
digits: "fa", // Return Persian digits: "۱۲۰۰۰"
addCommas: true // Add commas: "12,000"
});
// Fuzzy matching (fixes typos)
wordsToNumber("یگصد و بنجاه هزار", { fuzzy: true }); // 150000
🏛️ Validation
National ID Validation - Validate Iranian national codes
import { verifyIranianNationalId, getPlaceByIranNationalId, createIranianNationalId } from '@persian-tools/persian-tools';
// Validation
verifyIranianNationalId("0499370899"); // true
verifyIranianNationalId("1234567890"); // false
// Location lookup
getPlaceByIranNationalId("0084575948");
// { city: "تهران مرکزی", province: "تهران" }
// Generation
createIranianNationalId(); // "0499370899"
createIranianNationalId({ preventRepeatedDigits: true }); // "1234567890"
National ID Generation - Generate valid Iranian national codes
import {
createIranianNationalId,
createIranianNationalIdDetailed,
validateNationalIdChecksum
} from '@persian-tools/persian-tools';
// Basic generation
createIranianNationalId(); // "0499370899"
// Generate without repeated digits
createIranianNationalId({ preventRepeatedDigits: true }); // "1234567890"
// Detailed generation with metadata
const result = createIranianNationalIdDetailed({
preventRepeatedDigits: true,
maxRetries: 50
});
console.log(result.nationalId); // "1234567890"
console.log(result.checkDigit); // 0
console.log(result.attempts); // 1
console.log(result.hasRepeatedDigits); // false
console.log(result.digits); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
// Validate generated IDs
validateNationalIdChecksum(result.nationalId); // true
// Custom random generator (for testing)
createIranianNationalId({
randomGenerator: () => 0.5 // Always returns 0.5
});
Phone Number Validation - Iranian mobile numbers
import { isPhoneNumberValid, phoneNumberDetail } from '@persian-tools/persian-tools';
// Validation
isPhoneNumberValid("09123456789"); // true
isPhoneNumberValid("+989123456789"); // true
// Operator detection
phoneNumberDetail("09123456789");
// {
// province: ["البرز", "تهران", ...],
// operator: "همراه اول",
// type: ["permanent"]
// }
💰 Banking & Finance
Bank Card Validation - Validate and identify Iranian bank cards
import { verifyCardNumber, getBankNameFromCardNumber } from '@persian-tools/persian-tools';
// Card validation
verifyCardNumber("6037701689095443"); // true
// Bank identification
getBankNameFromCardNumber("6219861034529007"); // "بانک سامان"
Extract Card Numbers - Advanced card extraction with performance optimization
import { extractCardNumber, extractCardNumberWithMetrics } from '@persian-tools/persian-tools';
// Basic extraction with validation
const text = "Payment cards: 6037701689095443 and 6219-8610-3452-9007";
const cards = extractCardNumber(text, {
checkValidation: true,
detectBankNumber: true
});
console.log(cards);
// [
// {
// index: 1,
// base: "6037701689095443",
// pure: "6037701689095443",
// startIndex: 15,
// endIndex: 31,
// isValid: true,
// bankName: "بانک کشاورزی"
// },
// {
// index: 2,
// base: "6219-8610-3452-9007",
// pure: "6219861034529007",
// startIndex: 36,
// endIndex: 55,
// isValid: true,
// bankName: "بانک سامان"
// }
// ]
// TypeScript function overloads for type safety
const validatedCards = extractCardNumber(text, {
checkValidation: true,
detectBankNumber: false
}); // Returns ExtractCardNumberWithValidation[]
// Multi-format support (Persian, Arabic, separators)
const multiFormat = "Cards: ۶۰۳۷۷۰۱۶۸۹۰۹۵۴۴۳ and 6037_7016_8909_5443";
const results = extractCardNumber(multiFormat);
// Automatically normalizes all formats to: "6037701689095443"
// Fuzzy matching for masked cards
const maskedText = "My card: 6037-****-8909-5443";
const fuzzyResults = extractCardNumber(maskedText, {
enableFuzzyMatching: true,
checkValidation: false
});
// Large document optimization (1MB+ texts)
const hugeDocument = "Large document content...".repeat(10000);
const optimizedResults = extractCardNumber(hugeDocument, {
optimizeForLargeText: true,
maxResults: 10
});
// Performance monitoring with metrics
const { cardNumbers, metrics } = extractCardNumberWithMetrics(text, {
includeContext: true,
contextLength: 20
});
console.log(`Processed ${metrics.textLength} chars in ${metrics.processingTime}ms`);
console.log(`Found ${metrics.validCardNumbers} valid cards`);
console.log(cardNumbers[0].context?.before); // "Payment cards: "
IBAN/Sheba Validation - Iranian bank account validation
import { isShebaValid, getShebaInfo } from '@persian-tools/persian-tools';
// IBAN validation
isShebaValid("IR820540102680020817909002"); // true
// Bank info extraction
getShebaInfo("IR820540102680020817909002");
// {
// nickname: "parsian",
// name: "Parsian Bank",
// persianName: "بانک پارسیان",
// accountNumber: "020817909002"
// }
📝 Text Processing
Persian Text Validation - Validate and clean Persian text
import { isPersian, hasPersian, toPersianChars } from '@persian-tools/persian-tools';
// Persian detection
isPersian("سلام دنیا"); // true
isPersian("Hello World"); // false
hasPersian("This has فارسی text"); // true
// Character cleanup
toPersianChars("علي"); // "علی" (fixes Arabic chars)
Digit Conversion - Convert between number systems
import { digitsEnToFa, digitsFaToEn, digitsArToFa } from '@persian-tools/persian-tools';
// English to Persian
digitsEnToFa("123456"); // "۱۲۳۴۵۶"
// Persian to English
digitsFaToEn("۱۲۳۴۵۶"); // "123456"
// Arabic to Persian
digitsArToFa("٧٨٩"); // "۷۸۹"
🌍 Geographic & Utilities
Vehicle Plates - Parse Iranian license plates
import { getNumberPlateInfo } from '@persian-tools/persian-tools';
// Car plates
getNumberPlateInfo("12D45147").info;
// {
// template: "12 D 451 ایران 47",
// province: "مرکزی",
// type: "Car",
// category: "دیپلمات"
// }
// Motorcycle plates
getNumberPlateInfo(12345678).info;
// {
// template: "123-45678",
// province: "مرکز تهران",
// type: "Motorcycle"
// }
Time Utilities - Persian time formatting
import { timeAgo, remainingTime } from '@persian-tools/persian-tools';
// Time ago (Jalali calendar)
timeAgo("1400/03/17 17:55:00"); // "5 دقیقه قبل"
// Remaining time
remainingTime("2025-12-31T23:59:59Z").toString();
// "۱ سال و ۲ ماه و ۱۵ روز"
Slugify - Generate URL-safe slugs from Persian text
import { slugify, createSlug, slugifySimple } from '@persian-tools/persian-tools';
// Basic usage
slugify("سلام دنیا"); // "سلام-دنیا"
slugify("چگونه برنامهنویسی یاد بگیریم؟"); // "چگونه-برنامه-نویسی-یاد-بگیریم"
// Custom options
slugify("سلام دنیا", {
separator: "_", // Use underscore instead of dash
maxLength: 20, // Limit length
lowercase: false // Don't convert to lowercase
}); // "سلام_دنیا"
// Preserve numbers
slugify("سال ۱۴۰۰", { preserveNumbers: true }); // "سال-۱۴۰۰"
// Helper functions
createSlug("مقاله جدید"); // "مقاله-جدید"
slugifySimple("تست ساده"); // "تست-ساده"
Text Analysis - Comprehensive Persian text analysis
import { analyzeText, getTextSummary, getTextComplexity, cleanText } from '@persian-tools/persian-tools';
// Full analysis
const analysis = analyzeText("این یک متن فارسی است.");
// {
// statistics: {
// totalWords: 5,
// totalCharacters: 20,
// persianCharacters: 15,
// // ... more stats
// },
// language: {
// primaryLanguage: "persian",
// confidence: 95,
// isPurePersian: true
// },
// readability: {
// complexity: "ساده",
// readingTime: 1,
// averageWordsPerSentence: 5
// },
// suggestions: [...]
// }
// Quick helpers
getTextSummary("سلام دنیا");
// "متن شامل 2 کلمه در 1 جمله است. زبان اصلی: فارسی (100% اطمینان). زمان مطالعه تقریبی: 1 دقیقه."
getTextComplexity("این جمله ساده است"); // "ساده"
// Text cleaning
cleanText("سَلامٌ 123 دنیا"); // "سلام ۱۲۳ دنیا"
🏗️ Development
Prerequisites
- Bun ≥ 1.3 (as runtime and package manager)
Setup
git clone https://github.com/persian-tools/persian-tools.git
cd persian-tools
bun install
Scripts
bun run build # Build the library
bun run test # Run tests
bun run test:watch # Watch mode testing
bun run lint # Lint code
bun run format # Format code
bun run lint:fix # Fix linting issues
Architecture
- TypeScript: Full type safety with strict mode
- Build: Unbuild (dual ESM/CJS output)
- Testing: Vitest with comprehensive coverage
- Quality: ESLint + Prettier + Husky hooks
🌟 Who's Using Persian Tools?
![]() Maani |
Pooleno Exchange |
![]() Bank Maskan PWA |
![]() MyDong |
![]() Melkba |
Using Persian Tools in your project? Add it here!
In Memory of @mediv0 🕊️
This project is dedicated to the memory of @mediv0,
a valued contributor whose passion and work helped shape Persian Tools.
Your code lives on, and you will always be remembered in our community. ❤️
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Quick Contribution Steps:
- Install Bun (from https://bun.sh)
- Fork & Clone the repository
- Create a feature branch:
git checkout -b my-feature - Make your changes with tests
- Run
bun run testandbun run lintandbun run formatto ensure everything passes - Commit with conventional commits (e.g.
feat: add new utility function) - Submit a pull request
👨💻 Contributors
📄 License
MIT License - see LICENSE for details.
Made with ❤️ by the Persian developer community
📚 Documentation • ⭐ Star us on GitHub • 🐦 Share on Twitter • 📦 View on NPM



