The UAE Dirham got its Unicode codepoint — U+20C3 — in July 2025. The symbol won't render natively on most devices until Unicode 18.0 font support ships in late 2026. In the meantime, dirham gives you the correct codepoint today, backed by a web font that you'll delete in one line when OS support arrives.
v1.5.3 is a large release. Animated counters, masked inputs, live exchange rates, Web Components for every primitive, a Tailwind plugin, a Next.js font helper, React Native support, and OG card generation. This post covers all of it.
Installation
pnpm add dirham
# or
npm install dirham
# or
yarn add dirhamReact Components
DirhamSymbol
Renders an inline SVG. SSR-compatible, no font loading, fully tree-shakeable:
import { DirhamSymbol } from 'dirham/react';
<DirhamSymbol size={24} weight="bold" />
<DirhamSymbol size={48} weight="thin" />Nine weight variants map directly to surrounding typography: thin, extralight, light, regular, medium, semibold, bold, extrabold, black.
DirhamIcon
Font-based glyph — lighter markup, requires dirham/css:
import 'dirham/css';
import { DirhamIcon } from 'dirham/react';
<DirhamIcon size={24} weight="regular" />DirhamPrice
Combines the symbol with Intl.NumberFormat formatting:
import { DirhamPrice } from 'dirham/react';
<DirhamPrice amount={1250} />
<DirhamPrice amount={1500000} notation="compact" weight="bold" />
<DirhamPrice amount={100} useCode />
<DirhamPrice amount={750} locale="ar-AE" />| Prop | Default | Description |
|---|---|---|
amount | 0 | Numeric value |
locale | "en-AE" | Intl locale string |
decimals | 2 | Decimal places |
notation | "standard" | "standard" or "compact" |
useCode | false | Show AED instead of the symbol |
weight | "regular" | Symbol stroke weight |
className | — | Tailwind / CSS classes |
AnimatedDirhamPrice
60fps count-up animation from zero to the target amount:
import { AnimatedDirhamPrice } from 'dirham/react';
<AnimatedDirhamPrice amount={1250} />
<AnimatedDirhamPrice amount={5000000} notation="compact" duration={2000} />The duration prop controls animation length in milliseconds (default: 1000). All DirhamPrice props apply. Works with server-side rendering — the static value renders immediately, animation triggers on mount.
DirhamInput
Masked currency input that formats keystrokes as the user types:
import { DirhamInput } from 'dirham/react';
<DirhamInput
value={amount}
onChange={(val) => setAmount(val)}
placeholder="0.00"
locale="en-AE"
/>The onChange callback receives the raw numeric value, not the formatted string. Handles decimal separators, thousands grouping, and backspace correctly across en-AE and ar-AE locales.
Web Components
dirham/web-component ships four custom elements. Import the bundle once — it registers all four:
<script type="module" src="https://cdn.jsdelivr.net/npm/dirham/dist/web-component/index.js"></script>Or in a bundled project:
import 'dirham/web-component';<dirham-symbol>
<dirham-symbol size="24" weight="bold"></dirham-symbol><dirham-price>
<dirham-price amount="1250"></dirham-price>
<dirham-price amount="5000000" notation="compact"></dirham-price>
<dirham-price amount="100" use-code></dirham-price>
<dirham-price amount="750" locale="ar-AE"></dirham-price>| Attribute | Default | Description |
|---|---|---|
amount | 0 | Numeric value |
locale | "en-AE" | Intl locale |
decimals | 2 | Decimal places |
notation | "standard" | "standard" or "compact" |
use-code | — | Boolean; shows AED |
symbol-size | "1em" | SVG width/height |
weight | "regular" | Stroke weight |
<dirham-animated-price>
<dirham-animated-price amount="5000" duration="1500"></dirham-animated-price><dirham-input>
<dirham-input value="1250" locale="en-AE"></dirham-input>Vue
<script setup>
import 'dirham/web-component';
</script>
<template>
<dirham-symbol size="24" weight="bold" />
<dirham-animated-price amount="1250" />
<dirham-input value="500" />
</template>Angular
import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
import 'dirham/web-component';
@Component({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<dirham-price amount="1250"></dirham-price>
<dirham-animated-price amount="5000" duration="2000"></dirham-animated-price>
`
})
export class AppComponent {}Svelte
<script>
import 'dirham/web-component';
</script>
<dirham-symbol size="24" weight="bold"></dirham-symbol>
<dirham-price amount="1250"></dirham-price>JavaScript Utilities
import {
formatDirham,
parseDirham,
copyDirhamSymbol,
copyDirhamAmount,
addVAT,
removeVAT,
getVAT,
UAE_VAT_RATE,
convertFromAED,
convertToAED,
fetchExchangeRates,
DIRHAM_UNICODE,
DIRHAM_SYMBOL_TEXT,
DIRHAM_CURRENCY_CODE,
} from 'dirham';Formatting
formatDirham(1234.5) // ' 1,234.50'
formatDirham(1234.5, { locale: 'ar-AE' }) // '١٬٢٣٤٫٥٠ '
formatDirham(100, { useCode: true }) // 'AED 100.00'
formatDirham(1500000, { notation: 'compact' }) // ' 1.5M'
parseDirham(' 1,234.50') // 1234.5Clipboard
await copyDirhamSymbol() // copies (U+20C3)
await copyDirhamSymbol('html') // copies ⃃
await copyDirhamSymbol('css') // copies \20C3
await copyDirhamAmount(1250) // copies ' 1,250.00'UAE VAT
UAE_VAT_RATE // 0.05
addVAT(1000) // 1050
removeVAT(1050) // 1000
getVAT(1000) // 50
// Custom rate
addVAT(1000, 0.10) // 1100Currency Conversion
const rates = await fetchExchangeRates();
convertFromAED(1000, 'USD', rates) // ~272.00
convertToAED(272, 'USD', rates) // ~1000.00useDirhamRate Hook
import { useDirhamRate } from 'dirham/react';
function PriceDisplay() {
const { rate, loading, error } = useDirhamRate('USD');
if (loading) return <span>Loading...</span>;
if (error) return <span>Rate unavailable</span>;
return <span>1 AED = {rate} USD</span>;
}Next.js Integration
// app/layout.tsx
import { dirhamFont } from 'dirham/next';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={dirhamFont.variable}>
<body>{children}</body>
</html>
);
}/* app/globals.css */
@import 'dirham/css';Tailwind Plugin
// tailwind.config.ts
import dirhamPlugin from 'dirham/tailwind';
export default {
plugins: [dirhamPlugin],
};The plugin adds font-dirham, dirham-symbol, and weight utilities that match the DirhamSymbol weight system.
Font Variants
Five font styles, nine weights each:
| Import | Variant | Use case |
|---|---|---|
dirham/css | Default | General purpose |
dirham/font/sans/woff2 | Sans-serif | UI, fintech dashboards |
dirham/font/serif/woff2 | Serif | Editorial, long-form |
dirham/font/mono/woff2 | Monospace | Code, terminal displays |
dirham/font/arabic/woff2 | Arabic | ar-AE locale, RTL interfaces |
Weights: thin (100) → extralight → light → regular (400) → medium → semibold → bold (700) → extrabold → black (900).
React Native
import { DirhamSymbol, DirhamPrice } from 'dirham/react-native';
<DirhamPrice amount={1250} style={{ fontSize: 24, color: '#000' }} />OG Card Generation
// app/api/og/route.tsx (Next.js Edge Runtime)
import { ImageResponse } from 'next/og';
import { DirhamPriceCard } from 'dirham/og';
export const runtime = 'edge';
export function GET(request: Request) {
const { searchParams } = new URL(request.url);
const amount = Number(searchParams.get('amount') || 1250);
return new ImageResponse(
<DirhamPriceCard amount={amount} />,
{ width: 1200, height: 630 }
);
}For SVG output:
import { generatePriceCardSVG } from 'dirham/og';
const svg = generatePriceCardSVG({ amount: 1250, currency: 'AED' });CLI
npx dirham # Print symbol info and codepoint
npx dirham copy # Copy (U+20C3) to clipboard
npx dirham copy html # Copy ⃃
npx dirham copy css # Copy \20C3All Package Exports
| Export | Contents |
|---|---|
dirham | Core utilities: formatDirham, parseDirham, copyDirhamSymbol, copyDirhamAmount, addVAT, removeVAT, getVAT, UAE_VAT_RATE, convertFromAED, convertToAED, fetchExchangeRates, constants |
dirham/react | DirhamSymbol, DirhamIcon, DirhamPrice, AnimatedDirhamPrice, DirhamInput, useDirhamRate |
dirham/react-native | DirhamSymbol, DirhamPrice (React Native) |
dirham/web-component | <dirham-symbol>, <dirham-price>, <dirham-animated-price>, <dirham-input> |
dirham/next | dirhamFont (Next.js font helper) |
dirham/tailwind | Tailwind plugin |
dirham/og | DirhamPriceCard, generatePriceCardSVG |
dirham/css | CSS with @font-face (default variant) |
dirham/scss | SCSS with @font-face |
dirham/font/woff2 | Default WOFF2 font file |
dirham/font/sans/woff2 | Sans-serif variant |
dirham/font/serif/woff2 | Serif variant |
dirham/font/mono/woff2 | Monospace variant |
dirham/font/arabic/woff2 | Arabic variant |
Migration from v1.3.0
v1.5.3 is backward-compatible. Existing DirhamSymbol, DirhamIcon, DirhamPrice, formatDirham, and Web Component usage requires no changes. New components are additive.
If you were using dirham/css for font loading, keep it. The font system is unchanged — new variants are opt-in via specific import paths.
The Unicode Roadmap
dirham uses U+20C3 everywhere — in React components, Web Components, CSS classes, and JS utilities. When operating systems ship native Unicode 18.0 font support (expected late 2026 into 2027), the migration is a single line:
- import 'dirham/css';All components, all utilities, all Web Components continue working. The codepoint never changes.
Resources
- npm package
- GitHub repository
- Documentation
- Unicode 18.0 Character Charts
- Central Bank of UAE — Currency
