npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fex-to/precise-compact

v1.2.1

Published

Intl.NumberFormat wrapper that shows compact notation (K, M, thousand, million, लाख, 万) ONLY for exact numbers. Prevents precision loss - returns regular format (1,234) for approximations instead of misleading compact notation.

Readme

precise-compact

Intl.NumberFormat wrapper that shows compact notation ONLY for exact numbers

npm version npm downloads License: MIT Coverage TypeScript Node.js

Problem: Native Intl.NumberFormat with compact notation shows 1234 as "1.2K" (loses precision)
Solution: This library shows "1K" or "1 thousand" for exact 1000, but keeps "1,234" for non-exact 1234

Supports words (thousand, тысяча, тисяча, लाख, 万, พัน) and all numbering systems (Western, Ukrainian, Indian, Chinese, Japanese, Korean, Thai, Arabic)

FeaturesInstallationUsageAPI


✨ Features

  • 🎯 No approximations — Shows compact (1.5K, "1.5 thousand") only for exact values. Returns regular format (1,234) for non-exact instead of misleading "1.2K"
  • 📝 Word-based notation — Display "thousand", "million", "тысяча", "миллион", "тисяча", "мільйон" instead of K, M
  • 🌏 Multiple numbering systems — Western (K, M, B, T), Indian (लाख, करोड़), Chinese/Japanese/Korean (万, 億), Thai (พัน, ล้าน), Arabic (ألف, مليون)
  • 💱 Currency support — Works with all currencies: $1.5K, ₹1 लाख, ¥1万, €1 Tsd.
  • 🚀 Zero dependencies — Uses native Intl.NumberFormat API
  • High performance — ~3.2M ops/sec with minimal 2% overhead
  • 📦 Tiny & tree-shakeable — ESM/CJS with full TypeScript types
  • 100% test coverage — 169 tests including non-Western locales

📦 Installation

npm install @fex-to/precise-compact

🚀 Quick Start

import { PreciseCompact } from '@fex-to/precise-compact';

// Word-based notation (default: short forms like K, M)
const format = PreciseCompact({
  locale: 'en-US',
  compactDisplay: 'long', // 👈 Use words instead of letters
});

// ✅ Exact values → compact notation
format.format(1000); // "1 thousand"
format.format(1500); // "1.5 thousand"
format.format(2500000); // "2.5 million"

// ❌ Non-exact values → regular format (not "1.2K" which would be misleading)
format.format(1234); // "1,234" (not "1.2 thousand")

💡 Usage

Localized Word Formats ⭐

// English words
const formatEN = PreciseCompact({ locale: 'en-US', compactDisplay: 'long' });
formatEN.format(1000); // "1 thousand"
formatEN.format(1000000); // "1 million"
formatEN.format(1000000000); // "1 billion"

// Russian words
const formatRU = PreciseCompact({ locale: 'ru-RU', compactDisplay: 'long' });
formatRU.format(1000); // "1 тысяча"
formatRU.format(1000000); // "1 миллион"
formatRU.format(1000000000); // "1 миллиард"

// German words
const formatDE = PreciseCompact({ locale: 'de-DE', compactDisplay: 'long' });
formatDE.format(1000); // "1 Tausend"
formatDE.format(1000000); // "1 Million"

// Ukrainian words
const formatUA = PreciseCompact({ locale: 'uk-UA', compactDisplay: 'long' });
formatUA.format(1000); // "1 тисяча"
formatUA.format(1000000); // "1 мільйон"
formatUA.format(1000000000); // "1 мільярд"

// Short forms (K, M, B, T)
const formatShort = PreciseCompact({ locale: 'en-US', compactDisplay: 'short' });
formatShort.format(1500); // "1.5K" (default behavior)

Currency & Locales

const formatUSD = PreciseCompact({ locale: 'en-US', currency: 'USD' });
formatUSD.format(1500); // "$1.5K"
formatUSD.format(1234); // "$1,234.00"

const formatEUR = PreciseCompact({ locale: 'de-DE', currency: 'EUR' });
formatEUR.format(1000); // "1 Tsd. €"

Non-Western Numbering Systems 🌏

// 🇮🇳 Indian numbering system (लाख = lakh = 100,000 | करोड़ = crore = 10,000,000)
const formatHI = PreciseCompact({ locale: 'hi-IN', compactDisplay: 'long' });
formatHI.format(100000); // "1 लाख"
formatHI.format(150000); // "1.5 लाख"
formatHI.format(10000000); // "1 करोड़"

// 🇨🇳 Chinese (万 = wan = 10,000 | 億 = yi = 100,000,000)
const formatZH = PreciseCompact({ locale: 'zh-CN' });
formatZH.format(10000); // "1万"
formatZH.format(100000000); // "1亿"

// 🇯🇵 Japanese (万 = man = 10,000 | 億 = oku = 100,000,000)
const formatJA = PreciseCompact({ locale: 'ja-JP' });
formatJA.format(10000); // "1万"
formatJA.format(100000000); // "1億"

// 🇰🇷 Korean (만 = man = 10,000 | 억 = eok = 100,000,000)
const formatKO = PreciseCompact({ locale: 'ko-KR' });
formatKO.format(10000); // "1만"
formatKO.format(100000000); // "1억"

// 🇹🇭 Thai (พัน = thousand | ล้าน = million)
const formatTH = PreciseCompact({ locale: 'th-TH', compactDisplay: 'long' });
formatTH.format(1000); // "1 พัน"
formatTH.format(1000000); // "1 ล้าน"

// 🇸🇦 Arabic (ألف = thousand | مليون = million)
const formatAR = PreciseCompact({ locale: 'ar-SA', compactDisplay: 'long' });
formatAR.format(1000); // "١ ألف"
formatAR.format(1000000); // "١ مليون"

📖 API

PreciseCompact(options)

Creates a formatter instance.

Parameters:

| Option | Type | Default | Description | | ---------------- | ------------------- | --------- | ------------------------------------------------------------------------ | | locale | string | "en-US" | BCP 47 locale code (supports all Intl locales) | | currency | string | — | ISO currency code (e.g., "USD", "EUR", "INR") | | compactDisplay | "short" \| "long" | "short" | "long" for words (thousand, लाख), "short" for letters (K, M) |

Returns: { format(value: number): string }

🎯 How It Works

Exactness Check

A number is "exact" if it can be represented without approximation. Non-exact values fall back to regular format to avoid misleading compact notation.

(abs(value) × 10^decimals) % scale === 0

Examples:

| Input | Output | Reason | | --------- | ------------- | ------------------------------------------- | | 1000 | "1K" | ✅ Exact: 1000 ÷ 1000 = 1 | | 1500 | "1.5K" | ✅ Exact: 1500 ÷ 1000 = 1.5 (1 decimal) | | 1234 | "1,234" | ❌ Not exact → regular format (not "1.2K") | | 1000000 | "1M" | ✅ Exact: 1M ÷ 1M = 1 | | 1230000 | "1.23M" | ✅ Exact: 1.23M with 2 decimals | | 1234567 | "1,234,567" | ❌ Not exact → regular format (not "1.23M") |

Why? Native Intl.NumberFormat with notation: "compact" would show 1234 as "1.2K", losing precision. This library prevents that.

⚡ Performance

Benchmark (100,000 iterations):

| Implementation | Avg Time | Throughput | | ------------------ | -------- | ---------------- | | PreciseCompact | 31ms | 3.2M ops/sec | | Native compact | 30ms | 3.3M ops/sec | | Overhead | +1ms | 1.02× slower |

Minimal performance cost (2%) for exact number detection.

🌐 Browser & Node.js Support

Requires Intl.NumberFormat with compact notation support:

  • ✅ Node.js 18.17+ or 20+
  • ✅ Chrome 77+, Firefox 78+, Safari 14.1+, Edge 79+
  • ✅ All modern browsers and runtimes (Deno, Bun, etc.)

📄 License

MIT © fex-to


Made with ❤️ by fex-to

⭐ Star on GitHub🐛 Report Issue💡 Request Feature