BBizKit

format.phone

v0.1.0 latest

Format a phone number for human-readable display with country-specific grouping, per ITU-T E.164 and RFC 3966.

formatphonee164rfc3966displaygroupinginternational

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:

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'.