# dirham > dirham is an MIT-licensed npm package for showing and formatting the UAE Dirham sign, U+20C3 UAE DIRHAM SIGN, on the web: a web font mapped to U+20C3, inline SVG components for React and React Native, Web Components (``, ``, ``, ``), a Tailwind CSS plugin, a Next.js font helper, Open Graph price-card images, and AED formatting, VAT and currency-conversion helpers. Last verified: 5 October 2026. Maintainer: Pooya Golchian (https://pooyagolchian.com/). dirham is an independent open-source project and is not affiliated with the Central Bank of the UAE. The UAE Dirham sign is the official currency symbol of the UAE dirham (AED). The Central Bank of the UAE unveiled it on 27 March 2025, and Unicode 18.0, released on 16 September 2026, encodes it as U+20C3. As of October 2026, mainstream system fonts (Apple's San Francisco, Google's Noto and Roboto) don't include it yet, so this package ships a small web font that loads only for U+20C3, plus SVG components, so the sign renders today. Once your users' system fonts include U+20C3, you can drop the web font without changing any code. Accepted by the Unicode Technical Committee on 22 July 2025 (UTC #184, decision 184-C17) and published in Unicode 18.0 on 16 September 2026. The symbol artwork comes from the Central Bank of the UAE: dirham.svg in the GitHub repository is the official CBUAE SVG, and the font and component outlines are traced from it. Naming: the UAE Dirham sign is the Unicode character U+20C3. د.إ is the Arabic abbreviation of درهم إماراتي (Emirati dirham), and AED is the ISO 4217 code (numeric 784, 2 decimal places); neither is the sign. ## Links - [Live demo and docs](https://dirham.js.org/) - [npm](https://www.npmjs.com/package/dirham) - [GitHub](https://github.com/pooyagolchian/dirham) - [Unicode 18.0.0](https://www.unicode.org/versions/Unicode18.0.0/) - [Unicode Currency Symbols chart, U+20A0–U+20CF](https://www.unicode.org/charts/PDF/U20A0.pdf) - [UTC #184 minutes, decision 184-C17](https://www.unicode.org/L2/L2025/25181.htm#184-C17) - [CBUAE announcement, 27 March 2025](https://centralbank.ae/media/ckkp3s3f/cbuae-unveils-new-dirham-symbol-en.pdf) - [CBUAE Dirham Currency Symbol Guidelines v1.0](https://centralbank.ae/media/e4ebcgtb/the_guidelines_for_the_national_currency_symbol_uae_dirham_english.pdf) - [License (MIT)](https://github.com/pooyagolchian/dirham/blob/main/LICENSE) ## Installation ```bash npm install dirham pnpm add dirham yarn add dirham ``` ## Package Exports | Subpath | Description | |---|---| | `dirham` | Core JS/TS utilities (formatDirham, parseDirham, copyDirhamSymbol, copyDirhamAmount, VAT helpers, conversion, constants) | | `dirham/react` | React components (DirhamSymbol, DirhamIcon, DirhamPrice, AnimatedDirhamPrice, DirhamInput, useDirhamRate) | | `dirham/react-native` | React Native components (DirhamSymbol, DirhamPrice) — requires react-native-svg | | `dirham/web-component` | Framework-agnostic ``, ``, ``, `` custom elements | | `dirham/tailwind` | Tailwind CSS plugin with utility classes (dirham-bold, dirham-sm, etc.) | | `dirham/next` | Next.js font optimization (dirhamFont, dirhamFontConfig) | | `dirham/og` | Open Graph / social price cards (DirhamPriceCard for next/og, generatePriceCardSVG) | | `dirham/css` | CSS with @font-face for the Dirham web font | | `dirham/scss` | SCSS with @font-face for the Dirham web font | | `dirham/font/woff2` | WOFF2 font file | | `dirham/font/woff` | WOFF font file | | `dirham/font/ttf` | TTF font file | | `dirham/font/sans/woff2` | Sans-serif variant WOFF2 | | `dirham/font/serif/woff2` | Serif variant WOFF2 | | `dirham/font/mono/woff2` | Monospace variant WOFF2 | | `dirham/font/arabic/woff2` | Arabic variant WOFF2 | ## React Components ### DirhamSymbol (Recommended) Zero-config, SSR-safe, tree-shakeable SVG component. No font loading required. ```tsx import { DirhamSymbol } from "dirham/react"; ``` Props: - `size`: number | string (default: 24) — width & height in px or CSS unit - `color`: string (default: "currentColor") — fill color - `weight`: DirhamWeight (default: "regular") — visual weight - `aria-label`: string (default: "UAE Dirham") — accessible label Weight values: thin, extralight, light, regular, medium, semibold, bold, extrabold, black `dirham/react` also exports components that use React hooks, so with React Server Components (for example the Next.js App Router), import it in a Client Component (a file that starts with `"use client"`). ### DirhamPrice All-in-one price display component. Renders the SVG symbol inline with a formatted amount. ```tsx import { DirhamPrice } from "dirham/react"; ``` Props: - `amount`: number (required) — the numeric value to display - `locale`: string (default: "en-AE") — locale for number formatting; `ar-*` locales put the symbol after the amount and set `dir="rtl"` - `decimals`: number (default: 2) — decimal places - `useCode`: boolean (default: false) — show "AED" text instead of symbol - `notation`: "standard" | "compact" (default: "standard") — compact shows K/M/B - `symbolSize`: number | string (default: "1em") — size of the inline symbol - `weight`: DirhamWeight (default: "regular") — symbol weight ### AnimatedDirhamPrice Animated count-up/count-down price display using requestAnimationFrame. ```tsx import { AnimatedDirhamPrice } from "dirham/react"; ``` Props: - `amount`: number (required) — target value to animate to - `duration`: number (default: 600) — animation duration in ms - `easing`: "linear" | "easeIn" | "easeOut" | "easeInOut" (default: "easeOut") - `locale`, `decimals`, `useCode`, `notation`, `symbolSize`, `weight` — same as DirhamPrice ### DirhamInput Masked currency input with auto-formatting. Supports controlled and uncontrolled modes. ```tsx import { DirhamInput } from "dirham/react"; console.log(v)} /> ``` Props: - `value`: number | undefined — controlled value - `defaultValue`: number — initial value (uncontrolled mode) - `onChange`: (value: number | undefined) => void — called on value change; `undefined` when the input is cleared - `locale`: string (default: "en-AE") — locale for formatting - `decimals`: number (default: 2) — max decimal places - `min` / `max`: number — value clamping on blur - `showSymbol`: boolean (default: true) — show inline SVG symbol - `useCode`: boolean (default: false) — show AED text instead of symbol - `selectOnFocus`: boolean (default: true) — auto-select on focus ### useDirhamRate React hook for fetching and using live exchange rates. ```tsx import { useDirhamRate } from "dirham/react"; const { rate, convert, convertBack, loading, error, refetch } = useDirhamRate("USD"); ``` Returns: - `rate`: number | undefined — current exchange rate - `loading`: boolean — fetch in progress - `error`: string | undefined — error message - `convert(amount)`: number | undefined — convert AED to target currency (undefined until the rate has loaded) - `convertBack(amount)`: number | undefined — convert target currency to AED - `refetch()`: void — clear cache and re-fetch ### DirhamIcon Font-based icon component. Requires `dirham/css` to be imported. ```tsx import "dirham/css"; import { DirhamIcon } from "dirham/react"; ``` Props: - `size`: number | string (default: "inherit") — font size - `color`: string (default: "currentColor") — icon color - `as`: "i" | "span" (default: "i") — HTML tag - `className`: string — additional CSS classes - `aria-label`: string (default: "UAE Dirham") — accessible label ## JavaScript/TypeScript Utilities ### Constants ```ts import { DIRHAM_UNICODE, // "\u20C3" — the U+20C3 character DIRHAM_CODEPOINT, // 0x20C3 — numeric codepoint DIRHAM_HTML_ENTITY, // "⃃" — HTML numeric character reference DIRHAM_CSS_CONTENT, // "\\20C3" — for CSS pseudo-elements DIRHAM_CURRENCY_CODE, // "AED" — ISO 4217 code DIRHAM_SYMBOL_TEXT, // "د.إ" — the Arabic abbreviation (not the U+20C3 sign) DIRHAM_FONT_FAMILY, // "Dirham" — font family name for the web font } from "dirham"; ``` ### formatDirham(amount, options?) Format a number as a Dirham currency string. `Intl.NumberFormat` prints `AED` or `د.إ.` for AED and never U+20C3, so `formatDirham` inserts the sign itself, followed by a no-break space. The outputs below are JavaScript strings: `\u{20C3}` is the sign and `\u{A0}` is the no-break space. ```ts formatDirham(1234.5); // "\u{20C3}\u{A0}1,234.50" formatDirham(1234.5, { locale: "ar-AE" }); // "1,234.50\u{A0}\u{20C3}" (Latin digits) formatDirham(1234.5, { locale: "ar-AE-u-nu-arab" }); // "١٬٢٣٤٫٥٠\u{A0}\u{20C3}" (Arabic-Indic digits) formatDirham(100, { useCode: true }); // "AED\u{A0}100.00" formatDirham(100, { decimals: 0 }); // "\u{20C3}\u{A0}100" formatDirham(100, { symbolFirst: false }); // "100.00\u{A0}\u{20C3}" formatDirham(5000000, { notation: "compact" }); // "\u{20C3}\u{A0}5M" ``` Options: - `locale`: string (default: "en-AE") — locale for number formatting - `decimals`: number (default: 2) — decimal places - `symbolFirst`: boolean — symbol placement (default: after the amount for `ar-*` locales, before it otherwise) - `useCode`: boolean (default: false) — use "AED" instead of symbol - `separator`: string (default: no-break space, U+00A0) — between symbol and amount - `notation`: "standard" | "compact" (default: "standard") — compact uses K/M/B abbreviations Placement: the CBUAE guidelines put the sign before the amount, separated by a space, and say to use either the sign or AED, never both. Arabic locales put the sign after the number in logical order; inside a `dir="rtl"` container it displays to the left of the amount. ### parseDirham(formatted) Parse a formatted Dirham string back to a number. ```ts parseDirham("\u{20C3}\u{A0}1,234.50"); // 1234.5 parseDirham("AED 100.00"); // 100 parseDirham("د.إ 1,234.50"); // 1234.5 (also accepts the Arabic abbreviation) ``` ### copyDirhamSymbol(format?) Copy the Dirham symbol to the clipboard in various formats. ```ts import { copyDirhamSymbol } from "dirham"; await copyDirhamSymbol(); // copies "\u20C3" (unicode) await copyDirhamSymbol("html"); // copies "⃃" await copyDirhamSymbol("css"); // copies "\\20C3" await copyDirhamSymbol("arabic"); // copies "د.إ" (the Arabic abbreviation, not the sign) ``` Formats: `"unicode"` (default), `"html"`, `"css"`, `"arabic"` ### copyDirhamAmount(amount, options?) Copy a formatted Dirham amount to the clipboard. It copies exactly what `formatDirham` returns. ```ts import { copyDirhamAmount } from "dirham"; await copyDirhamAmount(1234.5); // copies "\u{20C3}\u{A0}1,234.50" await copyDirhamAmount(1234.5, { useCode: true }); // copies "AED\u{A0}1,234.50" ``` ### VAT Helpers UAE VAT calculation utilities (5% standard rate by default). ```ts import { addVAT, removeVAT, getVAT, UAE_VAT_RATE } from "dirham"; addVAT(100); // 105 removeVAT(105); // 100 getVAT(100); // 5 addVAT(100, { rate: 0.1 }); // 110 (custom rate) addVAT(99.99, { decimals: 4 }); // 104.9895 ``` Options: `rate` (default: 0.05), `decimals` (default: 2) ### Currency Conversion Convert between AED and other currencies. Rates fetched from open.er-api.com (no auth required), cached for 1 hour. ```ts import { convertFromAED, convertToAED, fetchExchangeRates, clearRateCache } from "dirham"; const usd = await convertFromAED(100, "USD"); const aed = await convertToAED(27.23, "USD"); const manual = await convertFromAED(100, "USD", { rate: 0.2723 }); // 27.23, no network request const rates = await fetchExchangeRates(); // { USD: 0.2723, EUR: 0.2511, ... } clearRateCache(); // force re-fetch on next call ``` Options: `decimals` (default: 2), `rate` (override, skips network fetch) ## Web Component Framework-agnostic custom elements, usable in any HTML page or framework (Vue, Angular, Svelte, etc.). ```html ``` `` attributes: `size`, `color`, `weight`, `aria-label` `` attributes: `amount`, `locale`, `decimals`, `notation`, `use-code`, `symbol-size`, `weight`, `currency` `` attributes: `amount`, `duration`, `easing`, `locale`, `decimals`, `notation`, `use-code`, `symbol-size`, `weight` `` attributes: `value`, `locale`, `decimals`, `min`, `max`, `placeholder`, `disabled`, `readonly`, `show-symbol`, `use-code`, `symbol-size`, `weight` — fires `dirham-change` with `{ detail: { value: number | null } }` Importing `dirham/web-component` in server-side code is safe: where `HTMLElement` and `customElements` don't exist (as in Node), the import doesn't throw and registers nothing. ## React Native Requires `react-native-svg` as a peer dependency. Same SVG path data as web version. ```tsx import { DirhamSymbol, DirhamPrice } from "dirham/react-native"; ``` DirhamSymbol props: `size` (default: 24), `color` (default: "#000"), `weight`, `accessibilityLabel` DirhamPrice props: `amount`, `locale`, `decimals`, `useCode`, `notation`, `symbolSize`, `weight`, `color`, `fontSize`, `accessibilityLabel` ## Tailwind CSS Plugin Provides utility classes for the Dirham symbol. No React dependency. ```js // tailwind.config.js import dirhamPlugin from "dirham/tailwind"; export default { plugins: [dirhamPlugin] }; ``` Utilities: - `.dirham` — base class, sets `font-family: Dirham, sans-serif` - `.dirham-thin` through `.dirham-black` — font weights 100 to 900 - `.dirham-xs` through `.dirham-4xl` — font sizes 0.75rem to 2.25rem - `.dirham-before` / `.dirham-after` — pseudo-elements that add the sign and a no-break space before or after the content - `.dirham-price` — component class (nowrap + tabular-nums) ## Next.js Font Optimization Pre-configured `next/font/local` instance. ```tsx import { dirhamFont } from "dirham/next"; ... // defines the --font-dirham CSS variable ⃃ ``` For manual setup: `import { dirhamFontConfig } from "dirham/next";` ## Open Graph Price Cards (dirham/og) Generate shareable price card images for Open Graph and Twitter Cards. ### Server-side SVG (zero dependencies) ```ts import { generatePriceCardSVG } from "dirham/og"; const svg = generatePriceCardSVG({ amount: 12500, title: "Monthly Rent", subtitle: "Dubai Marina, Studio", accentColor: "#22c55e", }); // Returns a self-contained string (1200×630 by default) ``` ### Next.js OG Image Route (`@vercel/og`) ```tsx // app/api/og/route.tsx import { ImageResponse } from "next/og"; import { DirhamPriceCard } from "dirham/og"; export const runtime = "edge"; export async function GET(request: Request) { const { searchParams } = new URL(request.url); const amount = Number(searchParams.get("amount") ?? "0"); const title = searchParams.get("title") ?? undefined; return new ImageResponse( , { width: 1200, height: 630 }, ); } ``` Then in your page ``: ```html ``` | Prop | Type | Default | Description | |------|------|---------|-------------| | `amount` | `number` | — | Price amount (required) | | `title` | `string` | — | Header text above the price | | `subtitle` | `string` | — | Footer text below the price | | `locale` | `string` | `"en-AE"` | Intl locale (RTL auto-detected) | | `decimals` | `number` | `2` | Decimal places | | `notation` | `"standard" \| "compact"` | `"standard"` | Number notation | | `width` | `number` | `1200` | Image width in px | | `height` | `number` | `630` | Image height in px | | `background` | `string` | `"#0a0a0a"` | Background color | | `textColor` | `string` | `"#ffffff"` | Text color | | `accentColor` | `string` | `"#22c55e"` | Dirham symbol & badge color | ## CDN Usage (No Install) Use via jsDelivr or unpkg without npm install: ```html ``` ## CLI ```bash npx dirham # prints symbol info table npx dirham copy # copies the U+20C3 character to the clipboard npx dirham copy html # copies ⃃ ``` Formats: `unicode`, `html`, `css`, `js`, `arabic`, `code` ## CSS / Web Font Usage ```ts import "dirham/css"; ``` ```html ``` To render U+20C3 inside your own text, put a Dirham family first in your font stack. Its `unicode-range` is `U+20C3`, so the browser downloads and uses it only for that character, and your typeface still draws everything else: ```css body { font-family: "Dirham-Sans", Inter, sans-serif; /* or "Dirham", "Dirham-Serif", "Dirham-Mono", "Dirham-Arabic" */ } ``` List it first rather than last: a family listed before it can claim U+20C3 and draw a box. Chrome resolves generic families such as `sans-serif` to a system font that draws its missing-glyph box, and some fonts, such as JetBrains Mono (checked October 2026), map U+20C3 to a placeholder glyph. ## Font Variants The CSS registers five font families: Dirham (default), Dirham-Sans, Dirham-Serif, Dirham-Mono and Dirham-Arabic. All five draw the same outline of the sign; Serif, Mono and Arabic only adjust its padding and proportions slightly, and Sans is identical to the default. Each WOFF2 file is about 1 KB. ## Unicode - Codepoint: U+20C3 UAE DIRHAM SIGN (Currency Symbols block, General Category Sc, UTF-8 E2 83 83, decimal 8387) - Unicode version: 18.0, released on 16 September 2026 (accepted by the Unicode Technical Committee on 22 July 2025, UTC #184, decision 184-C17) - Native font support (as of October 2026): Apple's system fonts (checked on macOS 26.6) and Google's Noto and Roboto don't include U+20C3 yet; Windows: not yet announced - Migration: when your users' system fonts include U+20C3, remove the web font import; text and components stay the same - Escapes: HTML `⃃` or `⃃` (numeric character reference; there is no named entity) · CSS `content: "\20C3"` · JavaScript/JSON `"\u20C3"` · URL `%E2%83%83` - Not an emoji: U+20C3 is a currency symbol (General Category Sc) ## Technical Details - Tree-shakeable ESM and CJS builds - TypeScript types included - React 17+ compatible (react is an optional peer dependency) - SSR-safe: the SVG components need no font loading, and `dirham/web-component` can be imported on the server - Zero runtime dependencies for the core module - Web Component (custom element) for framework-agnostic usage - CLI tool (`npx dirham`) for quick access