Number Words
Numbers and money in words, with the grammar — and any currency in any language.
npm install @devix-labs/number-words
Arabic that agrees with what it counts: gender polarity, duals, the tamyīz, the construct state. Urdu with its own word for every number to ninety-nine, and lakh and crore. English in both numbering systems. Then the parts nobody else ships: any currency spelled in any language — including AED in English, which is what a Dubai invoice is — the cheque line with “only” in the right language, and counting your own nouns. 5.1 KB, zero dependencies, identical to its PHP twin.
What you get
Arabic that agrees
Polarity (ثلاثة كتب but ثلاث سيارات), duals (درهمان), the tamyīz (أحد عشر درهمًا), the genitive after a round hundred, and the construct state (مئتا درهم).
Any currency, any language
AED in English, PKR in Urdu, INR in Arabic. Every other library locks the currency to its locale — which is why none of them can spell a Dubai invoice.
The cheque line
“AED twelve thousand … and fifty fils only”, with فقط لا غير or صرف in the right language, and both halves named even when one is zero.
Count your own nouns
Give Arabic the four forms of فاتورة once and every number agrees — ثلاث فواتير, إحدى عشرة فاتورةً, ألفا فاتورة.
Urdu, all ninety-nine of them
No rule derives اکتالیس from چالیس, so every numeral is written out — with lakh, crore and arab above a thousand.
Never a float
Money is split and rounded on the digits, and the integer side is bigint, so amounts past a double stay exact.
Number Words — overview
Why it exists
Spelling a number is solved in JavaScript: n2words does it well, in a hundred languages. This package does not claim otherwise.
It exists for the three things that are still missing, in every library we ran:
- Currency and language are locked together. No library will spell an AED amount in English — which is what a Dubai invoice is. Ours takes any currency in any language.
- No cheque line. Banks want "AED twelve thousand … and fifty fils only", in the cheque's own language. Ours prints it.
- You cannot count your own nouns. Arabic needs four forms of فاتورة to say ثلاث فواتير and إحدى عشرة فاتورةً. Ours takes them.
And in PHP, where ICU writes خمسة مائة, gets the gender of eleven wrong, has no Arabic ordinals and
answers in English when asked for Urdu, the whole thing is missing. That is the companion package,
devix/laravel-number-words.
Shape of the package
| Export | What |
|---|---|
toWords, toOrdinal |
the number, in words |
toMoney, toCheque |
an amount, with its currency's grammar |
counted, noun |
your own nouns, agreeing |
registerCurrency, registerLanguage |
extend either |
en, ar, ur |
the languages, if you want one directly |
Not in 1.0
Languages beyond these three — registerLanguage() takes yours — and invoice or cheque templates,
which are the Pro edition's shape.
How it compares
Questions
Isn't this solved already?
For spelling a number in JavaScript, largely yes — n2words is good and we say so in the teardown. This package exists for three things still missing everywhere: spelling any currency in any language (a Dubai invoice in English, priced in dirhams, which n2words and to-words both refuse), the cheque line with “only” in the right language, and counting your own nouns in Arabic. In PHP nothing usable exists at all.
What is wrong with Arabic in other libraries?
Usually the agreement. Three takes the opposite gender of what it counts (ثلاثة كتب but ثلاث سيارات), two is a dual (درهمان), eleven to ninety-nine take the accusative (أحد عشر درهمًا), a round hundred takes the genitive singular (مئة درهم), and a dual before its noun loses its nūn (مئتا درهم, never مئتان درهم). PHP's ICU gets several of these wrong and writes خمسة مائة for five hundred.
Can I count something other than money?
Yes, and it is the feature we are proudest of. Give counted() the four Arabic forms of your noun once — فاتورة, فاتورتان, فواتير, فاتورةً — and every number agrees, including ألفا فاتورة for two thousand.
Will the amount survive floating point?
Amounts are split and rounded on the digits, never on a float, and the integer side uses bigint, so values past what a double can hold are exact. Pass a string for money that came from a database.
Which currencies are included?
AED, SAR, QAR, KWD, BHD, JOD, OMR, EGP, PKR, INR, USD, EUR and GBP, each with words in English, Arabic and Urdu. KWD, BHD, JOD and OMR divide into a thousand and keep all three digits. registerCurrency() takes your own.
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.