Skip to content

For developers

The library is small: two functions, one options object, and typed errors. Every output on this page is computed by the library at build time, not typed by hand.

Not yet on npm

The name terbilang on npm belongs to an unrelated package, so the release name is not settled yet. Do not install the npm package called terbilang expecting this library. Until a release, install from source.

Install from source

git clone https://github.com/andifathulms/terbilangcd terbilangpnpm installpnpm build:lib

Builds dist/ — ESM, CJS, and type declarations. No runtime dependencies.

What is guaranteed

  • BigInt through the whole arithmetic path: still exact above 2⁵³, where number-based implementations start going silently wrong.
  • Every value from 0 to 1,000,000 is round-tripped one by one, on every commit.
  • format and parse are exact inverses under the same options.
  • Zero runtime dependencies. ESM and CJS, with type declarations.
  • A small, stable public surface: Rinci depends on it for payslips.

API

Nothing is thrown from the public surface. Every call returns a Hasil: { type: "ok", nilai } or { type: "galat", galat }.

format(nilai: bigint | string, opsi?: Partial<Options>): Hasil<string>

Number to words. Accepts a bigint or a digit string (thousands dots and a decimal comma are allowed). A number is refused with a typed error, never silently converted.

  • format(1_000_001n){ type: 'ok', nilai: 'satu juta satu' }
    Try in the converter →
  • format('1.500,25', { mataUang: 'rupiah', sen: 'sen' }){ type: 'ok', nilai: 'seribu lima ratus rupiah dua puluh lima sen' }
    Try in the converter →
  • format(9_007_199_254_740_993n){ type: 'ok', nilai: 'sembilan kuadriliun tujuh triliun seratus sembilan puluh sembilan miliar dua ratus lima puluh empat juta tujuh ratus empat puluh ribu sembilan ratus sembilan puluh tiga' }
    Try in the converter →
  • format(10n ** 18n){ type: 'galat', galat: { type: 'di-luar-jangkauan', … } }
    Try in the converter →
parse(kata: string, opsi?: Partial<Options>): Hasil<Terurai>

Words to number. Returns a Terurai — sign, the integer part as a bigint, and the fractional digits as written.

  • parse('dua ratus lima puluh ribu'){ type: 'ok', nilai: { negatif: false, bulat: 250000n, pecahan: '' } }
    Try in the converter →
  • parse('seribu juta'){ type: 'galat', galat: { type: 'skala-tanpa-kuantitas', … } }
    Try in the converter →

Options

Every option may be passed partially; anything omitted takes its default. The keys are stable — the converter uses the same keys in its URL hash. The usage behind each choice is on the Rules page.

KeyDefaultChoices
sejutafalse
  • false — satu juta
  • true — sejuta
ejaanMiliar'baku'
  • 'baku' — satu miliar, satu triliun
  • 'varian' — satu milyar, satu trilyun
mataUang'tidak'
  • 'tidak' — seribu lima ratus
  • 'rupiah' — seribu lima ratus rupiah
sen'koma'
  • 'koma' — 1,25 → satu koma dua lima
  • 'sen' — 1,25 → satu rupiah dua puluh lima sen
kapitalisasi'tidak'
  • 'tidak' — seribu lima ratus rupiah
  • 'kalimat' — Seribu lima ratus rupiah
  • 'judul' — Seribu Lima Ratus Rupiah

Refusals

The library refuses rather than guesses. Every error carries a type you can switch over exhaustively and a message naming exactly what failed.

typeMeaning
masukan-kosongEmpty input.
tipe-tidak-didukungUnsupported input type.
bukan-bilanganNot a valid number.
di-luar-jangkauanBeyond the citable range.
pecahan-terlalu-panjangSen mode accepts at most two decimal digits.
opsi-bertentanganThose options do not go together.
kata-tidak-dikenalUnrecognised word.
skala-tanpa-kuantitasScale word without a quantity.
urutan-skala-salahScale words are not in descending order.
susunan-tidak-sahInvalid word order.