npm package: @rmnddesign/format-currency
Description: A tiny utility to format currency values without the Intl boilerplate
Author: rmnddesign
Latest version: 1.0.0

# @rmnddesign/format-currency

A tiny utility to format currency values without the Intl boilerplate.

## The Problem

Formatting currency in JavaScript is verbose:

```js
new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
}).format(amount / 100)
```

And you have to remember:
- Divide by 100 to convert cents to dollars
- JPY and KRW don't have decimal places
- KWD and BHD have 3 decimal places
- Different locales format differently

This utility handles all of that for you.

## Installation

```bash
npm install @rmnddesign/format-currency
```

## Quick Start

```ts
import { formatCurrency } from "@rmnddesign/format-currency"

// Amount in cents (default)
formatCurrency(2422, "USD")   // "$24.22"
formatCurrency(2422, "EUR")   // "€24.22"
formatCurrency(2422, "GBP")   // "£24.22"
```

**That's it.** Pass cents, get a formatted string.

## Common Examples

### Basic formatting

```ts
// US Dollars
formatCurrency(2422, "USD")        // "$24.22"
formatCurrency(100000, "USD")      // "$1,000.00"

// Euros
formatCurrency(2422, "EUR")        // "€24.22"

// British Pounds
formatCurrency(2422, "GBP")        // "£24.22"

// Swiss Francs
formatCurrency(2422, "CHF")        // "CHF 24.22"
```

### Zero-decimal currencies

Some currencies don't use cents. The function handles this automatically:

```ts
// Japanese Yen (no decimals)
formatCurrency(1000, "JPY")        // "¥1,000"

// Korean Won (no decimals)
formatCurrency(50000, "KRW")       // "₩50,000"

// Vietnamese Dong (no decimals)
formatCurrency(100000, "VND")      // "₫100,000"
```

### Three-decimal currencies

Some currencies use 3 decimal places:

```ts
// Kuwaiti Dinar (3 decimals)
formatCurrency(1234, "KWD")        // "KWD 1.234"

// Bahraini Dinar (3 decimals)
formatCurrency(5000, "BHD")        // "BHD 5.000"
```

### Different locales

Change how the number is formatted based on locale:

```ts
// Dutch format (€ before, comma as decimal)
formatCurrency(2422, "EUR", { locale: "nl-NL" })  // "€ 24,22"

// German format (€ after, comma as decimal)
formatCurrency(2422, "EUR", { locale: "de-DE" })  // "24,22 €"

// French format
formatCurrency(2422, "USD", { locale: "fr-FR" })  // "24,22 $US"
```

### Amount already in dollars (not cents)

If your amount is already in main units (dollars, euros, etc.), set `fromCents: false`:

```ts
// Amount is already $24.22, not 2422 cents
formatCurrency(24.22, "USD", { fromCents: false })   // "$24.22"
formatCurrency(99.99, "EUR", { fromCents: false })   // "€99.99"
formatCurrency(1000, "GBP", { fromCents: false })    // "£1,000.00"
```

### Compact mode (no decimals)

When you don't need cent precision:

```ts
formatCurrency(2422, "USD", { compact: true })   // "$24"
formatCurrency(2499, "USD", { compact: true })   // "$25" (rounds)
formatCurrency(99999, "EUR", { compact: true })  // "€1,000"
```

### Display style

Change how the currency is displayed:

```ts
// Symbol (default)
formatCurrency(2422, "USD")                          // "$24.22"

// Currency code
formatCurrency(2422, "USD", { display: "code" })     // "USD 24.22"

// Currency name
formatCurrency(2422, "USD", { display: "name" })     // "24.22 US dollars"
```

### Combining options

```ts
// Dutch locale, compact
formatCurrency(2422, "EUR", { locale: "nl-NL", compact: true })
// "€ 24"

// Already in dollars, compact
formatCurrency(24.99, "USD", { fromCents: false, compact: true })
// "$25"

// German locale, currency code
formatCurrency(2422, "EUR", { locale: "de-DE", display: "code" })
// "24,22 EUR"
```

## API Reference

### formatCurrency(amount, currency, options?)

Formats a currency value.

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `amount` | `number` | The amount to format (in cents by default) |
| `currency` | `CurrencyCode` | ISO 4217 currency code (e.g., "USD", "EUR") |
| `options` | `FormatCurrencyOptions` | Optional formatting options |

**Options:**

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `locale` | `string` | `"en-US"` | Locale for number formatting |
| `fromCents` | `boolean` | `true` | If `true`, divides by 100 (or appropriate decimal places). Set to `false` if amount is already in main units. |
| `compact` | `boolean` | `false` | If `true`, removes decimal places |
| `display` | `"symbol" \| "code" \| "name"` | `"symbol"` | How to display the currency |

**Returns:** `string` - The formatted currency string

## Supported Currencies

All ISO 4217 currencies are supported. TypeScript will autocomplete currency codes for you:

```ts
formatCurrency(100, "USD")  // TypeScript knows all valid codes
formatCurrency(100, "XYZ")  // TypeScript error: invalid currency
```

<details>
<summary>Full list of supported currencies (click to expand)</summary>

AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN,
BAM, BBD, BDT, BGN, BHD, BIF, BMD, BND, BOB, BRL,
BSD, BTN, BWP, BYN, BZD, CAD, CDF, CHF, CLP, CNY,
COP, CRC, CUC, CUP, CVE, CZK, DJF, DKK, DOP, DZD,
EGP, ERN, ETB, EUR, FJD, FKP, GBP, GEL, GGP, GHS,
GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF,
IDR, ILS, IMP, INR, IQD, IRR, ISK, JEP, JMD, JOD,
JPY, KES, KGS, KHR, KMF, KPW, KRW, KWD, KYD, KZT,
LAK, LBP, LKR, LRD, LSL, LYD, MAD, MDL, MGA, MKD,
MMK, MNT, MOP, MRU, MUR, MVR, MWK, MXN, MYR, MZN,
NAD, NGN, NIO, NOK, NPR, NZD, OMR, PAB, PEN, PGK,
PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR,
SBD, SCR, SDG, SEK, SGD, SHP, SLL, SOS, SPL, SRD,
STN, SVC, SYP, SZL, THB, TJS, TMT, TND, TOP, TRY,
TTD, TVD, TWD, TZS, UAH, UGX, USD, UYU, UZS, VEF,
VES, VND, VUV, WST, XAF, XCD, XDR, XOF, XPF, YER,
ZAR, ZMW, ZWD

</details>

## Why cents by default?

Most payment systems (Stripe, PayPal, etc.) store amounts in the smallest currency unit (cents) to avoid floating-point precision issues:

```ts
// From your database or payment API
const priceInCents = 2999  // $29.99

// Just pass it directly
formatCurrency(priceInCents, "USD")  // "$29.99"
```

If you're working with decimal amounts, just set `fromCents: false`:

```ts
const price = 29.99
formatCurrency(price, "USD", { fromCents: false })  // "$29.99"
```

## License

MIT