format.phone
v0.1.0 latestFormat a phone number for human-readable display with country-specific grouping, per ITU-T E.164 and RFC 3966.
Format a phone number for human-readable display with country-specific grouping, per ITU-T E.164 and RFC 3966.
Signature
function phone(input: string | { countryCode: string; nationalNumber: string; extension?: string }, opt?: PhoneFormatOptions): string | null
Type Definitions:
PhoneFormatOptions— interface
Problem
Phone numbers stored in E.164 format or raw digit strings are not human-readable. Different countries use different digit grouping patterns (US: 3-3-4, JP: 2-4-4, FR: 1-2-2-2-2). Ad-hoc formatting with regex fails across country boundaries and style requirements (international vs national vs E.164 vs RFC 3966).
How It Works
Strips existing separators, auto-detects country from E.164 prefix table (~55 countries), applies country-specific grouping patterns from a built-in table (~20 countries). Supports 4 output styles: 'international' (default, +1 202 555 0173), 'national' (202 555 0173), 'e164' (+12025550173), and 'rfc3966' (tel:+12025550173). Accepts both string and structured { countryCode, nationalNumber } inputs.
Boundaries
- Returns null for empty, whitespace-only, or non-digit strings.
- Throws TypeError for non-string/non-object input.
- Countries without a grouping pattern in the built-in table fall through with no grouping applied.
Replaces
Common boilerplate this function replaces:
'+' + countryCode + ' ' + national.replace(/(\d{3})(\d{3})(\d{4})/, '$1 $2 $3')
Examples
format.phone("+12025550173"); // "+1 202 555 0173"
format.phone("+442079460958"); // "+44 2079 460 958"
format.phone("+12025550173", { style: "e164" }); // "+12025550173"
format.phone("+12025550173", { style: "rfc3966" }); // "tel:+12025550173"
format.phone("+12025550173", { style: "national" }); // "202 555 0173"
format.phone(""); // null
Standards
Caveats
- Country detection uses longest-prefix-first matching from the built-in E.164 table; ambiguous prefixes resolve to the first match.
- Grouping patterns cover ~20 major countries; numbers from unlisted countries are returned without digit grouping.
- The separator option only affects group separators in the output; it does not affect the '+' prefix or 'tel:' scheme.
FAQ
How to format a phone number with country code in JavaScript?
format.phone('+12025550173') returns '+1 202 555 0173' — auto-detects US country code and applies 3-3-4 grouping.
How to format a phone number in E.164 format?
format.phone('+12025550173', { style: 'e164' }) returns '+12025550173' — compact E.164 with no separators.
How to generate tel: URI links from phone numbers?
format.phone('+12025550173', { style: 'rfc3966' }) returns 'tel:+12025550173' — RFC 3966 compliant tel URI.
How to format a phone number without the country code prefix?
Use style 'national': format.phone('+12025550173', { style: 'national' }) returns '202 555 0173'.
How to format phone numbers from structured data?
Pass an object: format.phone({ countryCode: '1', nationalNumber: '2025550173' }) returns '+1 202 555 0173'.