Open source · MIT · Zero dependencies

Arabic formatting,
done right.

أرقامٌ وعملاتٌ وتواريخُ هجريةٌ ولغةٌ عربيةٌ سليمة — في سطرٍ واحد.

The formatting layer for every Arabic product: correct currency symbols for all 22 Arab countries, deterministic Umm al-Qura Hijri dates, number-to-words, cheque-grade تفقيط, six plural forms and RTL text that never breaks.

npm install arabicfmt
٢٢currencies of all 22 Arab states — correct symbols & precision
٦Arabic plural forms — the full six-form CLDR system
١٩٤tests (194), CLDR-verified data on every build
٠zero runtime dependencies. ESM + CJS + types

Everything on this page — 22 currencies, 300 years of Hijri tables, تفقيط, plurals, bidi, validators — ships in ≈ 11 kB min+gzip. Import one module and pay as little as 0.6 kB.

٠١ · the errata column

What everyone else gets wrong

Generic i18n libraries treat Arabic as an afterthought. arabicfmt treats it as the spec.

ProblemTypical libraryarabicfmt
Saudi riyal symbol ﷼ — that's the Iranian rial (U+FDFC) New U+20C1 sign, with a safe text fallback ر.س
Kuwaiti dinar decimals 1.20 د.ك — loses a digit of real money 1.200 د.ك — 3 decimals, CLDR-verified
Hijri dates Different output on Node, Chrome, Safari, Hermes Frozen Umm al-Qura tables — identical everywhere
Plurals "2 كتابs" — Arabic needs six forms, not two zero / one / two / few / many / other — automatic
Money in words (تفقيط) Hand-rolled, grammar breaks on duals ألفان وخمسمئة ريالٍ فقط لا غير — cheque-grade
Sorting names .sort() puts آلاء before ابتسام — codepoint order Real Arabic collation — hamza forms treated as one letter
Phone numbers in RTL +1 (555)… flips mid-sentence Unicode isolates wrap every LTR run automatically

٠٢ · the playground

Try the whole library

Everything below is computed live in your browser by arabicfmt — change anything.

Currency studio العملات

Correct symbol, correct precision, for every Arab currency — and the only library tracking the 2025–2026 Unicode currency-sign transition.

Symbol mode

The Unicode currency-sign transition, tracked for you

Spell money for cheques & invoices التفقيط

The legal Arabic wording every invoice and contract needs — with correct singular, dual, plural and accusative agreement, automatically.

Numbers → Arabic words كتابة الأعداد

Gender-aware, every scale from صفر to المليارات, plus true ordinals.

Gender
ordinal

Counting, inflected العدد والمعدود

العدد والمعدود — the hardest small rule in Arabic grammar. Give countedNoun() any noun's four forms and it picks the right one for any number.

Noun
Fraction
/ over
arabicFraction

Hijri dates التقويم الهجري

Official Umm al-Qura tables, frozen — the same answer on Node, Chrome, Safari and Hermes. No more off-by-one Ramadan.

Numerals
Language
toHijri()
fromHijri()

Six plural forms الجموع

Arabic has six grammatical plural categories. Drag the slider — watch the form change.

5
zeroonetwo fewmanyother

Parse it back قراءة الأرقام

Your users type ١٬٢٣٤٫٥٦ with Arabic separators — and your API wants a number. Formatting needs to work in both directions.

parseCurrency
parseNumber
toLatinDigits
toArabicDigits

Sort like a dictionary الترتيب والعطف

.sort() orders by codepoint, so آلاء lands before ابتسام. Arabic collation knows آ أ إ ا are one letter.

.sort()
sortArabic()
formatList

RTL rescue إصلاح الاتجاه

Phone numbers and Latin words scramble Arabic sentences. One function fixes the whole string.

without
isolateForeign()
isolateForeign(text) // wraps every LTR run in FSI…PDI

Everyday formatters يوميات المطوّر

The strings every app needs, with grammar no template can fake.

formatRelativeTime
formatDuration
formatFileSize
formatCompact
formatPercent
formatNumber

Text intelligence معالجة النصوص

Search that survives diacritics and hamza variants; slugs that survive Arabic.

stripTashkeel
normalizeForSearch
transliterate
slugify

Validation التحقق

Real ISO 7064 and Luhn checksums — not regexes that wave bad numbers through.

isValidIBAN(iban) && saudiIdType(id) // "citizen" | "resident"

٠٣ · common questions

Frequently asked

The Arabic-formatting problems developers hit most — and the one-line fix.

How do I show the Saudi Riyal symbol correctly in JavaScript?

Use formatCurrency(1234.5, { currency: "SAR" }). arabicfmt outputs the correct riyal — the new Unicode sign U+20C1 or the safe text symbol ر.س — instead of (U+FDFC), which is actually the Iranian rial.

How do I get a Hijri date that is identical on every browser and Node?

Use formatHijri(new Date()) from arabicfmt/umalqura. It uses frozen official Umm al-Qura tables, so the output is the same on Node, Chrome, Safari and React Native — no off-by-one Ramadan.

How do I convert Arabic numerals like ١٢٣ back to a JavaScript number?

Use parseNumber("١٬٢٣٤٫٥٦")1234.56. Plain parseInt can't read Eastern Arabic digits or Arabic separators.

How do I spell a money amount in Arabic words for a cheque (تفقيط)?

Use spellCurrency(1234.5, { currency: "SAR" }) — it returns the legal Arabic wording with correct singular, dual, plural and accusative agreement.

How do I stop phone numbers from scrambling Arabic (RTL) sentences?

Use isolateForeign(text) from arabicfmt/bidi. It wraps every left-to-right run in Unicode isolates (FSI…PDI) so the sentence stays readable.

Is arabicfmt really zero-dependency, and does it work in the browser?

Yes — zero runtime dependencies, ESM + CJS, full TypeScript types, ~11 kB. Works in Node, the browser (incl. via CDN: https://cdn.jsdelivr.net/npm/arabicfmt/+esm), Deno, Bun and React Native.

جاهز؟

Every Arabic string on this page was rendered live, in your browser, by arabicfmt.

npm install arabicfmt