@gks101/numtowords - v1.0.3
    Preparing search index...

    @gks101/numtowords - v1.0.3

    @gks101/numtowords

    bundle size license tree shaking dependency count

    Convert numbers to words in multiple languages and numeral systems — English, Indian, Hindi, German, French — with full TypeScript support, zero dependencies and < 3kb size.

    registerAllBuiltInLocales()
    convert(1_000_124) // "One million one hundred and twenty-four"
    convert(12.34) // "Twelve point three four"
    convert("150.50") // "One hundred and fifty point five zero"
    convert(1_000_124, { locale: "in" }) // "Ten lakh one hundred twenty-four"
    convert(1_000_124, { locale: "hi" }) // "दस लाख एक सौ चौबीस"
    convert("12.34", { locale: "hi" }) // "बारह दशमलव तीन चार"
    convert(1_000_124, { locale: "de" }) // "Eine Million einhundertvierundzwanzig"
    convert(1_000_124, { locale: "fr" }) // "Un million cent vingt-quatre"

    • 🌍 5 locales out of the boxen, in, hi, de, fr
    • 🇮🇳 Indian numbering system — lakh, crore, arab, kharab, neel, padma, shankh
    • 🔢 Decimal point support — converts decimal numbers and decimal strings digit by digit
    • 🔢 BigInt support — handles arbitrarily large numbers
    • 💱 Currency mode — locale-aware major/minor currency words
    • 🔌 Extensible — register your own locale in two lines
    • 📦 Three bundle formats — ESM, CJS, UMD (browser ready)
    • 🔷 Full TypeScript types included

    npm install @gks101/numtowords
    

    import { convert, registerAllBuiltInLocales } from '@gks101/numtowords';

    registerAllBuiltInLocales();

    convert(0); // "Zero"
    convert(42); // "Forty-two"
    convert(1_000_000); // "One million"
    convert(12.34); // "Twelve point three four"
    convert('150.50'); // "One hundred and fifty point five zero"

    Built-in locales are explicit. Register them once during app startup.

    import {
    registerBuiltInLocale,
    registerAllBuiltInLocales,
    } from '@gks101/numtowords';

    registerAllBuiltInLocales(); // registers en, in, hi, de, fr
    // or registerBuiltInLocale('en'); // register only one locale

    All examples below assume locales are registered.

    Decimal values are supported with . as the decimal separator. The integer part is converted normally, and the fractional part is converted digit by digit using the selected locale.

    convert(12.34); // "Twelve point three four"
    convert('150.50'); // "One hundred and fifty point five zero"
    convert('-0.25'); // "Negative zero point two five"
    convert('12.34', { locale: 'in' }); // "Twelve point three four"
    convert('12.34', { locale: 'hi' }); // "बारह दशमलव तीन चार"
    convert('12.34', { locale: 'de' }); // "Zwölf komma drei vier"
    convert('12.34', { locale: 'fr' }); // "Douze virgule trois quatre"

    Use a string when trailing zeros are meaningful:

    convert(150.5); // "One hundred and fifty point five"
    convert('150.50'); // "One hundred and fifty point five zero"
    convert(1_00_000, { locale: 'in' }); // "One lakh"
    convert(10_00_000, { locale: 'in' }); // "Ten lakh"
    convert(1_00_00_000, { locale: 'in' }); // "One crore"
    convert(1_00_000, { locale: 'hi' }); // "एक लाख"
    convert(1_00_00_000, { locale: 'hi' }); // "एक करोड़"
    convert(21, { locale: 'de' }); // "Einundzwanzig"
    convert(1_000_000, { locale: 'de' }); // "Eine Million"
    convert(2_000_000, { locale: 'de' }); // "Zwei Millionen"
    convert(70, { locale: 'fr' }); // "Soixante-dix"
    convert(80, { locale: 'fr' }); // "Quatre-vingts"
    convert(1_000_000, { locale: 'fr' }); // "Un million"

    Parameter Type Description
    input number | bigint | string The number to convert. Negative numbers, decimals with ., string input with commas/underscores, and BigInts are all supported.
    options ConvertOptions Optional configuration (see below).

    Returns string

    Option Type Default Description
    locale "en" | "in" | "hi" | "de" | "fr" | "auto" "en" Target language / numeral system
    capitalize boolean true Capitalise the first letter
    useAnd boolean true Include "and" connector (English only)
    currency boolean | string | CurrencyOptions false true = locale currency words, string = append label (legacy), object = full currency configuration
    ordinal boolean false Convert integer to ordinal words
    import {
    toWords,
    toOrdinalWords,
    toCurrencyWords,
    detectRuntimeLocale,
    registerBuiltInLocale,
    registerAllBuiltInLocales,
    availableLocales,
    registerLocale,
    getLocale,
    } from '@gks101/numtowords';

    registerBuiltInLocale('en');
    registerBuiltInLocale('fr');
    // or registerAllBuiltInLocales()

    toWords(42); // "Forty-two"
    toOrdinalWords(21, { locale: 'en' }); // "Twenty-first"
    toCurrencyWords('12.34', { locale: 'en' }); // "Twelve dollars and thirty-four cents"
    detectRuntimeLocale(); // e.g. "en"
    availableLocales(); // e.g. ["en", "fr"]

    convert(9_007_199_254_740_993n); // beyond Number.MAX_SAFE_INTEGER
    convert(1_00_00_00_00_000n, { locale: 'in' }); // "One arab"
    convert(42, { capitalize: false }); // "forty-two"
    
    convert(101, { useAnd: false }); // "One hundred one"
    
    convert('200.42', { locale: 'en', currency: true }); // "Two hundred dollars and forty-two cents"
    convert('200.42', { locale: 'in', currency: true }); // "Two hundred rupees and forty-two paise"
    convert('200.42', { locale: 'hi', currency: true }); // "दो सौ रुपये और बयालीस पैसे"
    convert('200.42', { locale: 'de', currency: true }); // "Zweihundert euro und zweiundvierzig cent"
    convert('200.42', { locale: 'fr', currency: true }); // "Deux cents euros et quarante-deux centimes"
    convert(5, { currency: 'USD' }); // "Five USD" (legacy suffix mode)

    convert('12.34', {
    locale: 'en',
    currency: {
    enabled: true,
    rules: {
    major: { one: 'credit', other: 'credits' },
    minor: { one: 'point', other: 'points' },
    joinWord: 'and',
    minorBase: 100,
    },
    },
    }); // "Twelve credits and thirty-four points"

    When currency is an object, you can fully control how currency values are rendered.

    type CurrencyOptions = {
    enabled?: boolean;
    code?: string; // resolves locale currencyDefaults (e.g. "USD", "INR", "EUR")
    roundMinor?: 'truncate' | 'round';
    includeOnly?: 'both' | 'major' | 'minor';
    rules?: {
    major: { one: string; other: string };
    minor: { one: string; other: string };
    joinWord?: string;
    minorBase?: 10 | 100 | 1000;
    hideZeroMinor?: boolean;
    };
    };

    Examples:

    // Resolve by currency code (uses locale defaults when available)
    convert('1.01', { locale: 'en', currency: { enabled: true, code: 'USD' } }); // "One dollar and one cent"

    // Round minor part (1.236 -> 1.24)
    convert('1.236', {
    locale: 'en',
    currency: { enabled: true, roundMinor: 'round' },
    }); // "One dollar and twenty-four cents"

    // Only major / only minor
    convert('12.34', {
    locale: 'en',
    currency: { enabled: true, includeOnly: 'major' },
    }); // "Twelve dollars"
    convert('12.34', {
    locale: 'en',
    currency: { enabled: true, includeOnly: 'minor' },
    }); // "Thirty-four cents"

    // Show zero minor part
    convert('12.00', {
    locale: 'en',
    currency: {
    enabled: true,
    rules: {
    major: { one: 'dollar', other: 'dollars' },
    minor: { one: 'cent', other: 'cents' },
    hideZeroMinor: false,
    },
    },
    }); // "Twelve dollars and zero cents"
    toOrdinalWords(1, { locale: 'en' }); // "First"
    toOrdinalWords(21, { locale: 'en' }); // "Twenty-first"
    convert(3, { locale: 'en', ordinal: true }); // "Third"

    Notes:

    • Ordinals are built-in for en and in. Other locales can support ordinals by implementing convertOrdinal.
    • Ordinal mode does not support decimals (e.g. "3.2").
    convert(5, { locale: 'auto' }); // uses navigator.language / LANG fallback
    
    convert(-1_500); // "Negative one thousand five hundred"
    

    You can add locales at runtime by calling registerLocale() with a LocaleDefinition. The convert function receives a bigint and the resolved options — return a string (do not capitalise; the library handles optional capitalization).

    Minimal stub:

    import { registerLocale, convert } from '@gks101/numtowords';

    registerLocale('es', {
    name: 'Spanish',
    decimalPoint: 'punto',
    decimalDigits: [
    'cero',
    'uno',
    'dos',
    'tres',
    'cuatro',
    'cinco',
    'seis',
    'siete',
    'ocho',
    'nueve',
    ],
    convert(n, _opts) {
    // minimal implementation — handle zero and fall back to a placeholder
    if (n === 0n) return 'cero';
    return 'número';
    },
    defaultCurrencyCode: 'EUR',
    currencyDefaults: {
    EUR: {
    major: { one: 'euro', other: 'euros' },
    minor: { one: 'centimo', other: 'centimos' },
    joinWord: 'y',
    minorBase: 100,
    hideZeroMinor: true,
    },
    },
    convertOrdinal(n, opts) {
    // Optional: implement real Spanish ordinals as needed; this is a placeholder.
    return `${this.convert(n, opts)}o`;
    },
    });

    convert(5, { locale: 'es' }); // "Número" (capitalisation applied by library)
    convert('5.25', { locale: 'es' }); // "Número punto dos cinco"

    Practical Spanish examples

    // Basic numbers
    convert(0, { locale: 'es' }); // "Cero"
    convert(1, { locale: 'es' }); // "Uno"
    // Hundreds and thousands
    convert(100, { locale: 'es' }); // "Cien"
    convert(101, { locale: 'es' }); // "Ciento uno"

    // Millions, accents and plurals
    convert(1_000_000, { locale: 'es' }); // "Un millón"
    convert(2_000_000, { locale: 'es' }); // "Dos millones"

    // Negative and currency examples
    convert(-5, { locale: 'es' }); // "Negativo cinco"
    convert(1, { locale: 'es', currency: 'EUR' }); // "Uno EUR" (legacy suffix mode)

    Notes

    • Your locale's convert should accept n: bigint and return the words in lowercase (prefer returning canonical forms with proper accents); the main library applies capitalization when capitalize: true.
    • You can optionally implement convertOrdinal(n, opts) for native ordinal support in your locale.
    • You can optionally provide currencyDefaults and defaultCurrencyCode for locale-native currency rendering.
    • Set decimalPoint and optionally decimalDigits to localize decimal output. Without decimalDigits, fractional digits fall back to calling your locale's convert for each digit.
    • Implementations may use BigInt arithmetic and should avoid throwing for valid numeric inputs.
    • For full correctness in Spanish, handle special forms (e.g., "cien" vs "ciento"), accents (dieciséis, veintidós), and pluralisation ("millón" → "millones").

    File Format Use case
    dist/index.esm.js ES Module Bundlers (Vite, webpack, Rollup)
    dist/index.cjs.js CommonJS Node.js (require)
    dist/index.umd.js UMD Browser <script> tags
    <script src="dist/index.umd.js"></script>
    <script>
    console.log(NumToWords.convert(1000000)); // "One million"
    </script>

    npm install
    npm run build # Rollup → dist/
    npm test # Jest test suite
    npm run test:coverage # Jest coverage report (coverage/lcov-report/index.html)
    npm run lint # TypeScript type check

    Value Indian Name English equivalent
    1,000 Thousand Thousand
    1,00,000 Lakh Hundred Thousand
    1,00,00,000 Crore Ten Million
    1,00,00,00,000 Arab Billion
    1,00,00,00,00,000 Kharab Hundred Billion
    1,00,00,00,00,00,000 Neel Ten Trillion
    1,00,00,00,00,00,00,000 Padma Quadrillion
    1,00,00,00,00,00,00,00,000 Shankh Hundred Quadrillion

    MIT