Validators
ID and tax number validation that tells you why — and admits when there was nothing to check.
npm install @devix-labs/validators
IBAN for every country in the registry, European VAT with fifteen verified check digits, and the numbers this region actually collects: Emirates ID, UAE TRN, Saudi ID and VAT, Qatar ID, Kuwait Civil ID, Bahrain CPR, Oman civil number, CNIC, NTN, PAN and GSTIN. Every answer carries a reason code you can turn into a message, and says whether a check digit was verified or only the shape. Formatting, input masks and test-data generators included. The PHP twin answers identically — 224 shared vectors keep them honest.
What you get
A reason, not a boolean
too-short, bad-structure, bad-checksum, unknown-country — so the message can say what to fix instead of “invalid”.
Honest about the check
Every result says checked: 'checksum' or 'structure'. A UAE TRN has no public check digit, and this will never pretend it does.
This region, properly
Emirates ID, TRN, Saudi ID and VAT, QID, Civil ID, CPR, CNIC, NTN, PAN, GSTIN — with real check digits where they exist. No mainstream library has them.
IBAN done carefully
All 78 registry countries: length, MOD 97-10, and the BBAN pattern plus bank code for the sixty whose structure is published here.
The same answers in PHP
224 shared vectors assert that the Laravel package agrees with the browser, down to the reason code and the formatting.
5.1 KB, tree-shakable
validator.js is 35.4 KB for its bundle and its most-reacted issue is about tree shaking. Import one validator and ship one validator.
Validators — overview
Why it exists
Three things are wrong with how identifiers get validated today. Libraries answer true or false,
so nobody can tell a person what to fix. They quietly claim to have checked numbers that have nothing
to check. And the regional numbers a business in Dubai, Riyadh, Karachi or Bengaluru actually collects
are missing entirely, so everyone writes their own regular expression.
What it does differently
- Reason codes. Every answer says why, in a vocabulary you can turn into a message.
- Honesty about the check.
checked: 'checksum'or'structure'— a number with no published check digit never pretends to have passed one. - This region, properly. Emirates ID, TRN, Saudi ID and VAT, QID, Civil ID, CPR, CNIC, NTN, PAN, GSTIN, with real check digits where they exist.
- One set of rules, two languages. 224 shared vectors assert that the PHP package answers exactly as the JavaScript one does.
- 5.1 kB, tree-shakable, no dependencies.
Shape of the package
| Export | What |
|---|---|
validate(kind, value, options?) |
the one way in |
iban, vat, emiratesId, cnic, gstin, … |
each validator on its own |
format, mask, generate, kinds |
writing, typing and test data |
luhn, mod97, luhn36, weightedMod11 |
the primitives, for your own numbers |
Not in 1.0
Live lookups — VIES for VAT, the FTA's TRN service, bank names from an IBAN — are the Pro edition's shape, because they need a network and a subscription. This package never makes a request.
Demos
All demos →How it compares
Questions
Why does “valid” sometimes mean less than it sounds?
Because some numbers have nothing to verify. A UAE TRN and a Pakistani CNIC carry no published check digit, so the most anyone can check is the shape. Every result says which happened in its `checked` field — treat 'structure' as “looks right”, not “is real”.
Which VAT numbers have their check digit verified?
AT, BE, DE, DK, FI, FR, GB, IE, IT, LU, NL, PL, PT, SE and SK. The other thirteen countries have their shape checked, and the result says so. Only VIES can tell you a number is actually registered.
Does it agree with the server?
That is the point. devix/laravel-validators is the same rules in PHP, and 224 shared vectors — real published numbers, generated ones and awkward input — assert both sides return the same reason code, the same cleaned value and the same formatting.
Can I use it for test data?
Yes. generate('emirates-id') returns a number that passes its own check digit and belongs to nobody; pass a seed for a fixture that stays stable between runs.
What about Arabic numerals and pasted spaces?
Handled. Arabic-Indic, Persian, Devanagari, Bengali and full-width digits are read as digits, and separators plus the invisible marks that come with a copy and paste are removed before anything is checked.
Does it make any network requests?
Never. Lookups against VIES, the FTA's TRN service or a bank directory need a network and a subscription; those are the Pro edition's shape.
More from Devix
All resources →Prayer Times
Library
Prayer times and Qibla direction with every calculation method.
VAT Calculator
Library
VAT and GST maths for the UAE, Saudi Arabia and Pakistan.
Arabic Slugify
Library
Slugs and transliteration for Arabic and Urdu text.