Skip to content
Devix Open Source

Guide

Getting started

composer require devix-labs/laravel-number-words

Nothing to publish. Three Blade directives and a facade are ready straight away.

In a template

<p>Total: {{ $invoice->total }}</p>
<p>In words: @money($invoice->total, 'AED')</p>
{{-- The cheque line a bank expects --}}
@cheque($payment->amount, 'AED')
{{-- AED twelve thousand three hundred forty-five dirhams and fifty fils only --}}

@words(1234) spells a plain number. All three take an optional language:

@money($invoice->total, 'AED', 'ar')
@words($count, 'ur')

Without one they follow config('number-words.language'), and that follows your application's locale — so a page rendered in Arabic prints its totals in Arabic.

In PHP

use Devix\NumberWords\Laravel\Facades\Words;

Words::toWords(1234);                                            // one thousand two hundred thirty-four
Words::toWords(1234, ['language' => 'ar']);                      // ألف ومئتان وأربعة وثلاثون
Words::toWords(12345678, ['language' => 'ur']);                  // ایک کروڑ تیئیس لاکھ پینتالیس ہزار چھ سو اٹھہتر
Words::toWords(12345678, ['system' => 'south-asian']);           // one crore twenty-three lakh…
Words::toOrdinal(21, ['language' => 'ar']);                      // الحادي والعشرون

Words::toMoney(1234.5, ['currency' => 'AED']);                   // one thousand … dirhams and fifty fils
Words::toMoney(1234.5, ['currency' => 'AED', 'language' => 'ar']);
Words::toCheque(1234.5, ['currency' => 'PKR', 'language' => 'ur']);

Or beside Laravel's own helper:

use Illuminate\Support\Number;

Number::spellWords(12345678, ['language' => 'ur']);
Number::spellMoney(1234.5, 'AED', 'ar');
Number::spellCheque(1234.5, 'AED');

Currencies

Thirteen are built in: AED, SAR, QAR, KWD, BHD, JOD, OMR, EGP, PKR, INR, USD, EUR and GBP — each with words in all three languages, so an English invoice can be priced in dirhams and an Arabic one in rupees.

The four Gulf currencies that divide into a thousand keep all three digits:

Words::toMoney(1.5, ['currency' => 'KWD']);   // one dinar and five hundred fils
Words::toMoney(1.5, ['currency' => 'AED']);   // one dirham and fifty fils

Add your own:

use Devix\NumberWords\{Currencies, Currency, NounForms};

Currencies::register(new Currency('BTC', 100_000_000,
    ['en' => new NounForms('bitcoin', 'bitcoin')],
    ['en' => new NounForms('satoshi', 'satoshis')],
));

Counting your own nouns in Arabic

This is where Arabic gets interesting, and where a plain spellout cannot help you:

use Devix\NumberWords\NounForms;

$invoices = new NounForms('فاتورة', 'فواتير', 'فاتورتان', 'فاتورةً', 'feminine');

Words::counted(1, $invoices, ['language' => 'ar']);    // فاتورة
Words::counted(2, $invoices, ['language' => 'ar']);    // فاتورتان        ← a dual
Words::counted(3, $invoices, ['language' => 'ar']);    // ثلاث فواتير     ← opposite gender
Words::counted(11, $invoices, ['language' => 'ar']);   // إحدى عشرة فاتورةً ← the tamyīz
Words::counted(2000, $invoices, ['language' => 'ar']); // ألفا فاتورة     ← the construct state

Give the four forms once and every number reads correctly.

Rounding

Money is split and rounded on the digits, never on a float:

Words::toMoney('1234.005', ['currency' => 'USD']);   // …and one cent
Words::toMoney(0.1 + 0.2, ['currency' => 'USD']);    // thirty cents

Agreeing with the browser

Use @devix-labs/number-words in the front end and this package on the server, and both print the same line. That is asserted, not assumed: 796 shared vectors run in this package's test suite.

Updated 15 Sep 2026