
Security News
Lovable’s OJ Rewrites Vite’s Dev Server in Rust as AI Lowers the Cost of Forking Open Source
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.
nepali-numbers-pro-max
Advanced tools
नेपाली number / NPR currency library for the Nepali developer community. Devanagari ↔ ASCII digits, Indian-style lakh/crore/arab grouping, NPR formatting, number → words (एक करोड पच्चीस लाख…), words → number, ordinals, fractions, compact, paisa-safe BigIn
The complete Nepali number toolkit. Devanagari ↔ ASCII digits, Indian-style lakh/crore grouping, NPR currency formatting, number → words (एक करोड पच्चीस लाख), words → number, paisa-safe BigInt math, ordinals, fractions, percentages, compact notation.
NepaliMoney Classएक to महाशंख (10²¹), one to mahashankh, in both languagestoNepaliWords ⟷ parseNepaliWords (no other npm package does this for Nepali)0.1 + 0.2 = 0.300000000000000041,23,45,67,890 not 1,234,567,890Rs., रु., रू, ₨, NPR"One thousand two hundred thirty-four rupees fifty-six paisa Only"sideEffects: false# npm
npm install nepali-numbers-pro-max
# pnpm
pnpm add nepali-numbers-pro-max
# yarn
yarn add nepali-numbers-pro-max
# bun
bun add nepali-numbers-pro-max
Works with Node ≥ 14, modern browsers, Deno, Bun, Cloudflare Workers, Vercel Edge.
import {
toDevanagariDigits,
groupNepali,
formatNPR,
formatNPRDevanagari,
toNepaliWords,
toNepaliCurrencyWords,
parseNepaliWords,
parseAmount,
NepaliMoney,
} from "nepali-numbers-pro-max";
// Digits
toDevanagariDigits("Rs. 1,234.56"); // "Rs. १,२३४.५६"
// Indian grouping
groupNepali(12345678); // "1,23,45,678"
// NPR
formatNPR(1234567.89); // "Rs. 12,34,567.89"
formatNPRDevanagari(1234567.89); // "रु. १२,३४,५६७.८९"
// Words
toNepaliWords(125_000_00); // "एक करोड पच्चीस लाख"
toNepaliCurrencyWords(1234.56);
// "एक हजार दुई सय चौँतीस रुपैयाँ छपन्न पैसा मात्र"
// Words → number (round-trip)
parseNepaliWords("एक करोड पच्चीस लाख"); // 12500000n
// Smart amount parser (Devanagari, NPR symbol, Indian grouping)
parseAmount("रु. १२,३४,५६७.८९");
// { paisa: 123456789n, value: 1234567.89, raw: "रु. १२,३४,५६७.८९", negative: false }
// Money class with paisa-safe arithmetic
NepaliMoney.fromRupees(0.1).add(0.2).rupees; // 0.3 (not 0.30000000000000004)
NepaliMoney.fromRupees(1000).multiply(1.13).formatNPR(); // "Rs. 1,130.00"
| Capability | nepali-number | nepali-number-words | get-nepali-number | ngx-nepali-number-to-words | nepali-numbers-pro-max |
|---|---|---|---|---|---|
| Last published | 2019 | 2026 | 2020 | 2020 | 2026 |
| TypeScript-first | partial | partial | no | yes (Angular) | ✅ strict |
| Zero deps | ✅ | ✅ | ✅ | tslib | ✅ |
| Devanagari ↔ ASCII | ✅ | ✅ | ✅ | partial | ✅ |
| Indian 3-2-2 grouping | ✅ | partial | ✅ | no | ✅ |
| NPR currency formatter | partial | partial | no | no | ✅ 5 symbols, accounting, compact |
| Number → Nepali words | ✅ | ✅ | no | ✅ (buggy paisa) | ✅ up to महाशंख |
| Number → English (Indian) words | ✅ | no | no | no | ✅ |
| Words → number (parser) | no | experimental | no | no | ✅ first-class, both languages |
| BigInt support | no | no | no | no | ✅ |
| Banker's rounding / paisa-int math | no | no | no | no | ✅ 6 modes |
| Compact (१.२ लाख / 1.5Cr) | partial | no | no | no | ✅ |
| Fractions (आधा, चौथाइ, डेढ) | no | no | no | no | ✅ |
| Ordinals (पहिलो, १०१st) | ✅ | no | no | no | ✅ irregular + suffix |
| Smart amount parser | partial | no | no | no | ✅ Devanagari + parens + symbols |
| Money class with chaining | no | no | no | no | ✅ NepaliMoney |
| Tree-shakeable per-function | no | no | no | no | ✅ |
| Tests | no | no | no | no | ✅ 105 passing |
| Rule | Why |
|---|---|
Indian-style 3-2-2 grouping is the default (1,23,45,67,890). | Nepal/India use it; Western 3-3-3 is opt-in via groupWestern. |
Functions split per language — *Nepali for Devanagari, *English…NepaliSystem for Roman. | Avoids { locale } option-bag noise. Each function has one job. |
Money uses BigInt paisa internally, exposes number rupees. | Sidesteps IEEE-754 drift. 0.1 + 0.2 always equals 0.3. |
English words use the Indian scale ladder (lakh/crore/arab), not Western (million/billion). | Mirrors how Nepali speakers express English numbers in everyday Nepal contexts. |
| Parsers accept Devanagari, ASCII, mixed, parens, NPR symbols. | Real input is messy — handle it. |
NPR symbol presets: Rs., रु., रू, ₨, NPR. | All five used in production banking software. |
formatNPR(1234567.89); // "Rs. 12,34,567.89"
formatNPR(1234567.89, { symbol: "NPR" }); // "NPR 12,34,567.89"
formatNPR(1234567.89, { precision: 0 }); // "Rs. 12,34,568"
formatNPR(-500); // "-Rs. 500.00"
formatNPRDevanagari(1234567.89); // "रु. १२,३४,५६७.८९"
formatNPRAccounting(-500); // "(Rs. 500.00)"
formatNPRCompact(2_50_00_000); // "Rs. 2.5Cr"
formatNPRCompact(150_000); // "Rs. 1.5L"
| Function | Output |
|---|---|
formatNPR(n) | Rs. 12,34,567.89 |
formatNPRDevanagari(n) | रु. १२,३४,५६७.८९ |
formatNPRAccounting(-n) | (Rs. 500.00) |
formatNPRCompact(n) | Rs. 2.5Cr, Rs. 1.5L, Rs. 1.2K |
stripNprSymbol(s) | strips Rs./रु./रू/₨/NPR |
Up to 10²¹ (महाशंख) via BigInt internally.
toNepaliWords(0); // "शून्य"
toNepaliWords(99); // "उनान्सय"
toNepaliWords(125); // "एक सय पच्चीस"
toNepaliWords(99999); // "उनान्सय हजार नौ सय उनान्सय"
toNepaliWords(125_000_00); // "एक करोड पच्चीस लाख"
toNepaliWords(1_00_00_00_000); // "एक अर्ब"
toNepaliWords(-25); // "ऋणात्मक पच्चीस"
toNepaliWords(100000000000000000000n); // "दश महाशंख"
toEnglishWordsNepaliSystem(125_000_00); // "one crore twenty-five lakh"
// Currency words
toNepaliCurrencyWords(1234.56);
// "एक हजार दुई सय चौँतीस रुपैयाँ छपन्न पैसा मात्र"
toNepaliCurrencyWordsWithoutMatra(1234); // "एक हजार दुई सय चौँतीस रुपैयाँ"
toNepaliCurrencyWordsBare(1234.5); // "एक हजार दुई सय चौँतीस पचास"
toEnglishCurrencyWordsNepaliSystem(1234.56);
// "one thousand two hundred thirty-four rupees fifty-six paisa only"
toChequeStyleEnglish(1234.56);
// "One thousand two hundred thirty-four rupees fifty-six paisa Only"
The Indian scale ladder used: हजार (10³) → लाख (10⁵) → करोड (10⁷) → अर्ब (10⁹) → खर्ब (10¹¹) → नील (10¹³) → पद्म (10¹⁵) → शंख (10¹⁷) → महाशंख (10¹⁹).
The headline reverse-direction feature. Round-trips with the words generators.
parseNepaliWords("एक करोड पच्चीस लाख"); // 12500000n
parseNepaliWords("दुई हजार र पच्चीस"); // 2025n (र = "and" connector)
parseNepaliWords("ऋणात्मक पच्चीस"); // -25n
parseEnglishWordsNepaliSystem("one crore twenty-five lakh"); // 12500000n
parseEnglishWordsNepaliSystem("one hundred and twenty-five"); // 125n
parseNepaliCurrencyWords("एक हजार रुपैयाँ पच्चीस पैसा मात्र");
// { rupee: 1000n, paisa: 25, negative: false }
parseEnglishCurrencyWordsNepaliSystem(
"one thousand rupees twenty-five paisa only",
);
// { rupee: 1000n, paisa: 25, negative: false }
// Smart string-amount parser
parseAmount("रु. १२,३४,५६७.८९");
// { paisa: 123456789n, value: 1234567.89, raw: "...", negative: false }
parseAmount("(Rs. 100.00)"); // { paisa: -10000n, negative: true, ... }
safeParseAmount("not a number"); // null
canonicalizeAmount("रु. १,२३४.५६"); // "1234.56"
groupNepali(0); // "0"
groupNepali(1234); // "1,234"
groupNepali(12345); // "12,345"
groupNepali(123456); // "1,23,456"
groupNepali(12345678); // "1,23,45,678"
groupNepali(1234567890); // "1,23,45,67,890"
groupNepali(123456.789); // "1,23,456.789"
groupNepali(-12345); // "-12,345"
groupNepali(123456789012345n); // "12,34,56,78,90,12,345" (BigInt)
groupNepaliDevanagari(12345678); // "१,२३,४५,६७८"
groupWestern(12345678); // "12,345,678"
compareGrouping(12345678);
// { nepali: "1,23,45,678", western: "12,345,678" }
NepaliMoney ClassImmutable money object with paisa-precise arithmetic.
import { NepaliMoney } from "nepali-numbers-pro-max";
const total = NepaliMoney.fromRupees(1234.56)
.add(NepaliMoney.fromRupees(100))
.multiply(1.13) // add 13% VAT
.subtract(50);
total.formatNPR(); // "Rs. 1,458.05"
total.formatNPRDevanagari(); // "रु. १,४५८.०५"
total.toNepaliWords(); // "एक हजार चार सय अन्ठाउन्न रुपैयाँ पाँच पैसा मात्र"
// Allocate without losing rupees to rounding
NepaliMoney.fromRupees(10).allocate(3).map(p => p.rupees);
// [3.34, 3.33, 3.33] — sums to exactly 10
// Comparison
const a = NepaliMoney.fromRupees(100);
const b = NepaliMoney.fromRupees(200);
a.lessThan(b); // true
a.compare(b); // -1
// Parse straight from a formatted string
NepaliMoney.parse("रु. १,२३४.५६").rupees; // 1234.56
Internal representation is signed BigInt paisa — no FP drift, supports values past Number.MAX_SAFE_INTEGER.
// Compact
formatCompactEnglish(1234); // "1.2K"
formatCompactEnglish(125000); // "1.3L"
formatCompactEnglish(2_50_00_000); // "2.5Cr"
formatCompactEnglish(2_50_00_000, { long: true }); // "2.5 crore"
formatCompactNepali(1234); // "१.२ हजार"
formatCompactNepali(125000); // "१.३ लाख"
formatCompactNepali(2_50_00_000); // "२.५ करोड"
// Percent
formatPercent(25); // "25%"
formatPercent(25.5, { precision: 1 }); // "25.5%"
formatPercentDevanagari(25); // "२५%"
percentToNepaliWords(25); // "पच्चीस प्रतिशत"
percentToEnglishWords(25.5); // "twenty-five point five percent"
// Fractions
fractionToNepaliWords(1, 2); // "आधा"
fractionToNepaliWords(3, 4); // "तीन चौथाइ"
fractionToNepaliWords(2, 3); // "दुई तिहाइ"
fractionToEnglishWords(3, 4); // "three quarters"
decimalToNepaliFraction(0.5); // "आधा"
decimalToNepaliFraction(0.42); // null
// Ordinals
toNepaliOrdinal(1); // "पहिलो"
toNepaliOrdinal(10); // "दशौँ"
toNepaliOrdinal(11); // "एघारऔँ"
toEnglishOrdinal(21); // "21st"
toEnglishOrdinal(113); // "113th"
| Function | Description |
|---|---|
toDevanagariDigits(input) | Convert digits in string to Devanagari (०-९). |
toAsciiDigits(input) | Convert digits in string to ASCII (0-9). |
toDevanagariChar(ch) | Single-char converter (throws if invalid). |
toAsciiChar(ch) | Single-char converter (throws if invalid). |
detectScript(s) | "ascii" | "devanagari" | "mixed" | "none" |
normalizeDigits(s, "ascii" | "devanagari") | Coerce mixed strings to one script. |
isAllAsciiDigits(s) | True if every char is 0-9. |
isAllDevanagariDigits(s) | True if every char is ०-९. |
DEVANAGARI_DIGITS, ASCII_DIGITS | Constant lookup tables. |
| Function | Description |
|---|---|
groupNepali(n, opts?) | Indian-style 3-2-2 grouping (1,23,45,678). |
groupNepaliDevanagari(n, opts?) | Same, in Devanagari digits. |
groupWestern(n, opts?) | Western 3-3-3 grouping (12,345,678). |
compareGrouping(n) | { nepali, western }. |
Options: { separator?: string, decimal?: string }.
| Function | Output style |
|---|---|
formatNPR(n, opts?) | Rs. 12,34,567.89 |
formatNPRDevanagari(n, opts?) | रु. १२,३४,५६७.८९ |
formatNPRAccounting(n, opts?) | (Rs. 500.00) for negatives |
formatNPRCompact(n, opts?) | Rs. 2.5Cr, Rs. 1.5L, Rs. 1.2K |
stripNprSymbol(s) | Remove Rs., रु., रू, ₨, NPR |
FormatNprOptions: { symbol, precision, rounding, symbolPosition, symbolSpacing, devanagari, separator, decimal }.
| Function | Example output |
|---|---|
toNepaliWords(n) | "एक करोड पच्चीस लाख" |
toEnglishWordsNepaliSystem(n) | "one crore twenty-five lakh" |
toNepaliCurrencyWords(amount) | "… रुपैयाँ … पैसा मात्र" |
toNepaliCurrencyWordsWithoutMatra(amount) | drops मात्र suffix |
toNepaliCurrencyWordsBare(amount) | no रुपैयाँ/पैसा labels |
toEnglishCurrencyWordsNepaliSystem(amount) | "… rupees … paisa only" |
toEnglishCurrencyWordsWithoutOnly(amount) | drops only suffix |
toEnglishCurrencyWordsBare(amount) | no rupees/paisa labels |
toChequeStyleEnglish(amount) | capitalized cheque-style |
| Function | Returns |
|---|---|
parseNepaliWords(s) | bigint |
parseEnglishWordsNepaliSystem(s) | bigint |
parseNepaliCurrencyWords(s) | { rupee, paisa, negative } |
parseEnglishCurrencyWordsNepaliSystem(s) | { rupee, paisa, negative } |
parseAmount(s) | { paisa, value, raw, negative } |
safeParseAmount(s) | ParsedAmount | null |
canonicalizeAmount(s) | normalized "1234.56" form |
isValidAmount(s) | boolean |
isValidNepaliDigitString(s) | boolean |
isValidAsciiNumberString(s) | boolean |
| Function | Description |
|---|---|
roundPaisa(n, mode?, precision?) | 6 rounding modes |
roundToScale(n, scale, mode?) | round to nearest 1000, 1L, 1Cr, etc. |
rupeeToPaisa(rupee) | number → bigint |
paisaToRupee(paisa) | bigint → number |
splitRupeePaisa(amount) | { rupee: bigint, paisa: 0-99, negative } |
addAmount(a, b) | FP-drift-free addition |
subtractAmount(a, b) | FP-drift-free subtraction |
multiplyAmount(a, factor, mode?) | rounded to paisa |
divideAmount(a, divisor, mode?) | rounded to paisa |
splitAmount(amount, n) | n-way split with remainder distribution |
toFixedAmount(n, decimals?) | drift-free toFixed |
Rounding modes: "half-up" \| "half-even" \| "half-down" \| "ceil" \| "floor" \| "trunc".
| Function | Example |
|---|---|
formatCompactEnglish(n, opts?) | 1.2K, 1.5L, 2.5Cr |
formatCompactNepali(n, opts?) | १.२ हजार, १.५ लाख, २.५ करोड |
formatPercent(n, opts?) | 25% |
formatPercentDevanagari(n, opts?) | २५% |
percentToNepaliWords(n) | पच्चीस प्रतिशत |
percentToEnglishWords(n) | twenty-five percent |
fractionToNepaliWords(num, den) | आधा, तीन चौथाइ |
fractionToEnglishWords(num, den) | half, three quarters |
decimalToNepaliFraction(v, tol?) | आधा for 0.5, null if no match |
toNepaliOrdinal(n) | पहिलो, दोस्रो, एघारऔँ |
toEnglishOrdinal(n) | 1st, 2nd, 113th |
NepaliMoney class| Method | Description |
|---|---|
NepaliMoney.fromRupees(n) | from rupees number |
NepaliMoney.fromPaisa(p) | from BigInt paisa |
NepaliMoney.parse(s) | parse formatted string |
NepaliMoney.zero() | zero instance |
.rupees, .paisa, .negative, .isZero | accessors |
.split() | { rupee, paisa, negative } |
.add(x) / .subtract(x) | x can be NepaliMoney or number |
.multiply(factor) / .divide(divisor) | scalar math, paisa-rounded |
.negate() / .abs() | sign helpers |
.allocate(n) | n-way split, no rupee lost |
.equals(o) / .greaterThan(o) / .lessThan(o) / .compare(o) | comparison |
.formatNPR(opts?), .formatNPRDevanagari(), .formatNPRAccounting(), .formatCompact() | formatting |
.toNepaliWords() / .toEnglishWords() | currency words |
.toString() | default formatNPR() |
.toJSON() | canonical "1234.56" |
| Constant | Description |
|---|---|
DEVANAGARI_DIGITS, ASCII_DIGITS | digit tables |
SCALES | scale ladder up to महाशंख |
NEPALI_ONES | 0-99 lookup table |
ENGLISH_ONES, ENGLISH_TENS | English word tables |
NEPALI_HUNDRED | "सय" |
RUPEE_WORD_NE, RUPEE_WORD_EN | "रुपैयाँ" / "rupees" |
PAISA_WORD_NE, PAISA_WORD_EN | "पैसा" / "paisa" |
MATRA_NE, ONLY_EN | "मात्र" / "only" |
NEGATIVE_NE, NEGATIVE_EN | "ऋणात्मक" / "negative" |
AND_NE, AND_EN | "र" / "and" |
NEPALI_ORDINALS_LOW | irregular 1-10 |
NEPALI_FRACTIONS_TABLE | curated fraction words |
import { NepaliMoney } from "nepali-numbers-pro-max";
const subtotal = NepaliMoney.fromRupees(50000);
const vat = subtotal.multiply(0.13);
const total = subtotal.add(vat);
console.log(total.formatNPRDevanagari()); // "रु. ५६,५००.००"
console.log(total.toNepaliWords());
// "छपन्न हजार पाँच सय रुपैयाँ मात्र"
import { toChequeStyleEnglish } from "nepali-numbers-pro-max";
const chequeText = toChequeStyleEnglish(1_25_000.50);
// "One lakh twenty-five thousand rupees fifty paisa Only"
import { parseAmount, formatNPRDevanagari } from "nepali-numbers-pro-max";
const userInput = "रु. १,२३,४५६.७८";
const parsed = parseAmount(userInput);
console.log(parsed.value); // 123456.78
console.log(formatNPRDevanagari(parsed.value)); // "रु. १,२३,४५६.७८"
import { NepaliMoney } from "nepali-numbers-pro-max";
const dinner = NepaliMoney.fromRupees(2575.65);
const split = dinner.allocate(4);
// First person pays 1 paisa more (no rupee disappears)
console.log(split.map(p => p.formatNPR()));
// [ "Rs. 643.92", "Rs. 643.91", "Rs. 643.91", "Rs. 643.91" ]
import { NepaliMoney } from "nepali-numbers-pro-max";
const items = [49.99, 19.95, 4.50, 2.75];
const total = items.reduce(
(sum, item) => sum.add(item),
NepaliMoney.zero(),
);
total.formatNPR(); // "Rs. 77.19" — exact, no FP error
number rupee accessor is lossy past Number.MAX_SAFE_INTEGER / 100 ≈ 90 trillion rupees. For larger values, use .paisa directly."half-even" for accounting-grade tax math.०) to U+0966+9 (९). Other Indic digit ranges (Tamil, Bengali, etc.) are not transliterated — Devanagari only.PRs welcome. Open an issue for:
npm install
npm test
npm run typecheck
npm run build
MIT © 2026 l3lackcurtains
Made with ❤️ for the Nepali developer community.
बनाइएको नेपाली डेभलपर समुदायको लागि।
FAQs
नेपाली number / NPR currency library for the Nepali developer community. Devanagari ↔ ASCII digits, Indian-style lakh/crore/arab grouping, NPR formatting, number → words (एक करोड पच्चीस लाख…), words → number, ordinals, fractions, compact, paisa-safe BigIn
We found that nepali-numbers-pro-max demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.