E.164 Phone Number Normalizer

Normalize local and international phone input into E.164 format with country dial codes, trunk-prefix handling and length checks.

JavascriptForm Validation

Code

snippet
const DIAL_CODES = {
  US: "1",
  GB: "44",
  CN: "86",
  DE: "49",
  IN: "91",
  JP: "81",
};

export function normalizePhone(input, options = {}) {
  if (typeof input !== "string") throw new TypeError("phone number must be a string");
  const { defaultCountry = "US" } = options;
  if (!Object.prototype.hasOwnProperty.call(DIAL_CODES, defaultCountry)) {
    throw new RangeError(`unsupported default country "${defaultCountry}"`);
  }
  const dialCode = DIAL_CODES[defaultCountry];
  const trimmed = input.trim();
  if (trimmed === "") throw new Error("phone number is empty");
  const hadPlus = trimmed.startsWith("+");
  let digits = trimmed.replace(/\D/g, "");
  if (!hadPlus && digits.startsWith("00")) {
    digits = digits.slice(2);
  } else if (!hadPlus) {
    digits = digits.replace(/^0+/, "");
    digits = `${dialCode}${digits}`;
  }
  if (digits.length < 8 || digits.length > 15) {
    throw new RangeError("E.164 numbers contain 8 to 15 digits");
  }
  if (digits.startsWith("0")) throw new Error("E.164 national numbers cannot start with zero");
  return `+${digits}`;
}

console.log(normalizePhone("(415) 555-0132"));
console.log(normalizePhone("+44 20 7946 0958"));
console.log(normalizePhone("0049 30 12345678"));
console.log(normalizePhone("0132 555 0199", { defaultCountry: "CN" }));