Validating Real Phone Numbers with  JavaScript

How to validate a phone number against the North American Numbering Plan with only JavaScript, no APIs required.

Validating phone numbers in web forms is a common task, but it’s often complicated by the variety of phone number formats used worldwide.

Here are few approaches I’ve used for validating phone numbers with JavaScript, as well as an overview of the best one: libphonenumber-js.

Common Phone Number Validation Patterns

Simple Regex for Basic Patterns

The simplest way to validate a phone number is to check for digits, with optional country codes or delimiters. For example, validating a North American phone number format:

function validatePhoneNumber(phoneNumber) {
    const regex = /^\+?1?\d{10}$/; // Matches +1XXXXXXXXXX or XXXXXXXXXX
    return regex.test(phoneNumber);
}

While simple regex can handle some cases, it’s not robust enough for international formats or edge cases like extensions.

Parsing North American Numbering Plan (NANP)

The NANP defines the format for phone numbers in the United States, Canada, and several other countries. A valid NANP phone number follows this pattern:

A basic validation for NANP numbers:

function validateNANP(phoneNumber) {
    const regex = /^\+1\s?\(?([2-9][0-8][0-9])\)?[-.\s]?([2-9][0-9]{2})[-.\s]?([0-9]{4})$/;
    return regex.test(phoneNumber);
}

This regex enforces NANP-specific rules, such as area codes not starting with 0 or 1. However, handling international numbers requires more advanced solutions.

The Best Solution: libphonenumber-js

libphonenumber-js is the most reliable library for phone number validation and formatting. It’s based on Google’s open-source library used in Android’s operating system and supports global phone number standards.

Key Features of libphonenumber-js

Installing the Library

Install libphonenumber-js via npm:

npm install libphonenumber-js

Basic Validation Example

Here’s how to validate a phone number with libphonenumber-js:

import { parsePhoneNumberFromString } from 'libphonenumber-js';

function validatePhoneNumber(phoneNumber, defaultCountry = 'US') {
    const phone = parsePhoneNumberFromString(phoneNumber, defaultCountry);
    return phone ? phone.isValid() : false;
}

console.log(validatePhoneNumber('+14155552671')); // true
console.log(validatePhoneNumber('555-2671', 'US')); // false

This example defaults to the US for parsing, but the library works for any country.

Formatting a Phone Number

libphonenumber-js also lets you format phone numbers for user-friendly display:

import { parsePhoneNumberFromString } from 'libphonenumber-js';

function formatPhoneNumber(phoneNumber, defaultCountry = 'US') {
    const phone = parsePhoneNumberFromString(phoneNumber, defaultCountry);
    return phone ? phone.formatInternational() : null;
}

console.log(formatPhoneNumber('+14155552671')); // +1 415 555 2671
console.log(formatPhoneNumber('4155552671', 'US')); // +1 415 555 2671

How Google Uses libphonenumber

Google developed libphonenumber as part of the Android operating system to handle global phone number validation. It adheres to international numbering plans, including NANP, and validates numbers for over 200 countries. This ensures that Android apps can reliably manage contacts, messaging, and telephony APIs.

How It Handles NANP

For NANP numbers, libphonenumber-js enforces strict rules:
– Area codes must follow NANP guidelines (e.g., no 0 or 1 as the first digit).
– Local numbers must match the 3-3-4 format.

Here’s an example:

import { parsePhoneNumberFromString } from 'libphonenumber-js';

const nanpNumber = '+14155552671';
const phone = parsePhoneNumberFromString(nanpNumber, 'US');

if (phone && phone.isValid() && phone.country === 'US') {
    console.log('Valid NANP number:', phone.formatNational());
} else {
    console.log('Invalid phone number');
}

Conclusion

Validating phone numbers can be tricky due to varying formats and standards, but tools like libphonenumber-js make it seamless. Whether you’re working with North American or international numbers, this library provides robust validation, formatting, and compatibility with global standards.

If you’re developing forms, integrating libphonenumber-js ensures reliability, especially for mobile-friendly apps and global users.

Have you used libphonenumber-js or other libraries for phone number validation? Share your experience in the comments!