awesome-phonenumber vs google-libphonenumber vs intl-tel-input vs libphonenumber-js vs phone
Phone Number Handling Libraries
awesome-phonenumbergoogle-libphonenumberintl-tel-inputlibphonenumber-jsphoneSimilar Packages:

Phone Number Handling Libraries

Phone number handling libraries in JavaScript provide tools for validating, formatting, and parsing phone numbers according to international standards. They help developers ensure that phone numbers are correctly formatted, validated against country-specific rules, and can be easily manipulated for various applications, such as forms, messaging systems, and telecommunication services. These libraries often support features like internationalization, normalization, and integration with input fields to enhance user experience and data accuracy.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
awesome-phonenumber0707734 kB172 months agoMIT
google-libphonenumber01,480618 kB333 months ago(MIT AND Apache-2.0)
intl-tel-input08,1924.15 MB12 days agoMIT
libphonenumber-js0-8.77 MB-2 days agoMIT
phone091788 kB12 months agoMIT

Feature Comparison: awesome-phonenumber vs google-libphonenumber vs intl-tel-input vs libphonenumber-js vs phone

Size and Performance

  • awesome-phonenumber:

    awesome-phonenumber is a small library (around 10KB minified) that provides fast validation and formatting of phone numbers. Its lightweight nature makes it ideal for performance-sensitive applications where quick operations are needed without significant resource consumption.

  • google-libphonenumber:

    google-libphonenumber is a larger library (over 200KB minified) due to its comprehensive features, including detailed validation and formatting for all countries. While it may impact load times, its accuracy and reliability make it worth the trade-off for applications that require thorough phone number handling.

  • intl-tel-input:

    intl-tel-input is a moderately sized library (about 50KB minified) that enhances input fields for international phone numbers. Its size is justified by the rich user interface features it provides, including country code selection and flag icons, which improve the user experience in web forms.

  • libphonenumber-js:

    libphonenumber-js is a lightweight alternative to Google’s libphonenumber, with a modular design that allows you to include only the parts you need. This reduces the overall bundle size while still providing good validation and formatting capabilities, making it suitable for modern web applications that prioritize performance.

  • phone:

    phone is a small and efficient library focused on phone number validation and formatting. Its simplicity and low overhead make it a great choice for applications that need quick and reliable phone number handling without the complexity of larger libraries.

Validation Accuracy

  • awesome-phonenumber:

    awesome-phonenumber provides accurate validation for phone numbers based on a curated list of international formats. It is particularly effective for quick validation tasks, but it may not cover all edge cases or provide the same level of detail as more comprehensive libraries.

  • google-libphonenumber:

    google-libphonenumber offers the highest level of validation accuracy, as it is based on Google’s extensive dataset of phone numbers from around the world. It validates numbers against country-specific rules, ensuring reliable results for both domestic and international numbers, making it the gold standard for phone number validation.

  • intl-tel-input:

    intl-tel-input focuses on validating phone numbers based on the selected country’s format. While it provides good validation for the country code and format, it relies on the user to select the correct country, which may lead to inaccuracies if users are not careful.

  • libphonenumber-js:

    libphonenumber-js provides accurate validation and formatting based on the international phone number standards. It is a lightweight implementation of Google’s libphonenumber, offering reliable validation without the bloat, making it suitable for applications that need accurate but efficient phone number handling.

  • phone:

    phone offers basic validation for phone numbers, including checks for format and country codes. While it is reliable for general use, it may not be as comprehensive as other libraries in handling international formats or providing detailed validation.

User Interface Integration

  • awesome-phonenumber:

    awesome-phonenumber is primarily a backend library with no built-in UI components. It can be easily integrated into forms and applications to validate and format phone numbers, but it does not provide any user interface elements.

  • google-libphonenumber:

    google-libphonenumber is also a backend-focused library that does not include UI components. It is designed to be integrated into applications where phone number validation and formatting are needed, but developers will need to create their own UI for input fields.

  • intl-tel-input:

    intl-tel-input excels in user interface integration by providing a ready-to-use input field for international phone numbers. It includes features like country code dropdowns and flag icons, making it highly user-friendly and reducing the likelihood of input errors in web forms.

  • libphonenumber-js:

    libphonenumber-js is a library that focuses on phone number validation and formatting, leaving UI integration up to the developer. It can be easily combined with custom input fields and forms, but it does not provide any pre-built user interface components.

  • phone:

    phone is a simple library that provides validation and formatting functions for phone numbers. It can be easily integrated into forms and applications, but it does not include any user interface elements or components.

Ease of Use: Code Examples

  • awesome-phonenumber:

    Phone Number Validation with awesome-phonenumber

    import { isValidNumber, formatNumber } from 'awesome-phonenumber';
    
    const number = '+14155552671';
    const isValid = isValidNumber(number);
    const formatted = formatNumber(number, 'US');
    
    console.log(`Is valid: ${isValid}`); // Is valid: true
    console.log(`Formatted: ${formatted}`); // Formatted: (415) 555-2671
    
  • google-libphonenumber:

    Phone Number Validation with google-libphonenumber

    import { PhoneNumberUtil, PhoneNumberFormat } from 'google-libphonenumber';
    
    const phoneUtil = PhoneNumberUtil.getInstance();
    const number = phoneUtil.parse('+14155552671', 'US');
    const isValid = phoneUtil.isValidNumber(number);
    const formatted = phoneUtil.format(number, PhoneNumberFormat.NATIONAL);
    
    console.log(`Is valid: ${isValid}`); // Is valid: true
    console.log(`Formatted: ${formatted}`); // Formatted: +1 415-555-2671
    
  • intl-tel-input:

    International Phone Input with intl-tel-input

    <input type="tel" id="phone" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/intlTelInput.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/css/intlTelInput.min.css" />
    <script>
      const input = document.getElementById('phone');
      window.intlTelInput(input, {
        initialCountry: 'us',
        geoIpLookup: function(callback) {
          fetch('https://ipinfo.io/json?token=YOUR_TOKEN')
            .then(response => response.json())
            .then(data => callback(data.country))
            .catch(() => callback('us'));
        },
      });
    </script>
    
  • libphonenumber-js:

    Phone Number Validation with libphonenumber-js

    import { parsePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
    
    const phoneNumber = parsePhoneNumber('+14155552671');
    const isValid = isValidPhoneNumber('+14155552671');
    const formatted = phoneNumber.formatNational();
    
    console.log(`Is valid: ${isValid}`); // Is valid: true
    console.log(`Formatted: ${formatted}`); // Formatted: (415) 555-2671
    
  • phone:

    Phone Number Validation with phone

    import { validate, format } from 'phone';
    
    const number = '+14155552671';
    const { isValid, countryCode } = validate(number);
    const formatted = format(number);
    
    console.log(`Is valid: ${isValid}`); // Is valid: true
    console.log(`Country Code: ${countryCode}`); // Country Code: US
    console.log(`Formatted: ${formatted}`); // Formatted: (415) 555-2671
    

How to Choose: awesome-phonenumber vs google-libphonenumber vs intl-tel-input vs libphonenumber-js vs phone

  • awesome-phonenumber:

    Choose awesome-phonenumber if you need a lightweight library focused on validating and formatting phone numbers with a simple API. It is particularly useful for projects that require quick validation without the overhead of a large library.

  • google-libphonenumber:

    Choose google-libphonenumber if you need a comprehensive solution with extensive validation, formatting, and parsing capabilities. It is based on Google's libphonenumber and is suitable for applications that require accurate international phone number handling.

  • intl-tel-input:

    Choose intl-tel-input if you need a user-friendly input field for international phone numbers with built-in country code selection and flag icons. It is ideal for web forms where you want to enhance the user experience while collecting phone numbers.

  • libphonenumber-js:

    Choose libphonenumber-js if you need a modular and lightweight alternative to Google’s libphonenumber. It offers good validation and formatting capabilities while allowing you to include only the parts you need, reducing bundle size.

  • phone:

    Choose phone if you need a simple and straightforward library for phone number validation and formatting. It is easy to use and integrates well with forms, making it a good choice for projects that require basic phone number handling.

README for awesome-phonenumber

npm version downloads build status minzipped size Dependency count

Awesome phonenumber parser

This library is a pre-compiled version of Google's libphonenumber, with a slightly simpler interface. It has a minimal footprint - is by far the smallest libphonenumber-based library available on npmjs, and has no dependencies.

Unlike libphonenumber, it includes a findNumbers( ) function to find phone numbers in text.

TypeScript typings are provided within the package.

Uses libphonenumber v9.0.24

Versions

  • v3:
    • Changed API (although with backwards compatible ABI)
    • Added ESM export
  • v4:
    • Changed API to be much cleaner
      • No constructor
      • No functions on returned object
      • No errors being thrown
    • Not backwards compatible, although like v3 except:
      • The second argument to parsePhoneNumber is an object
        • E.g. { regionCode: 'SE' } instead of a region code string
      • The return value is like toJSON( ) on v3
  • v5:
    • Dropped Node 12 support
  • v6:
    • Dropped Node 16 support
  • v7:
    • Added findNumbers( ) feature, to find phone numbers in text
    • Added support for short numbers

Comparison with other libraries

Since this library is pre-compiled, it doesn't depend on the closure compiler, and needs not load it on start. This makes the library faster and saves you a lot of space. It also means this library is trivial to use in any webpack project (or using any other means to run in the browser).

Among all the popular phone number using Google's libphonenumber (or mimicing it), only this one, google-libphonenumber and libphonenumber-js have decent README's with examples. This may have changed since first doing these benchmarks.

A library should be quick to load (require()), quick to parse first time and all consecutive times. It shouldn't bloat your node_modules, and it should have a small memory footprint, if possible.

The following is the result of a test program which loads the library, then parses a phone number, and then once again. It's called 100 times for each library and the mean values are shown here. Parsing a phone number first time might be slower because of initially compiling/optimizing regular expressions and whatnot. Parsing a phone number a second time will show the speed of likely all future parsing within that process.

Actionawesome-phonenumber
7.2.0
(lib 8.13.47)
google-libphonenumber
3.2.38
(lib 8.13.42)
libphonenumber-js
1.11.9
(lib -)
Load library first time7.82 ms ✅14.28 ms14.53 ms
Parse first phone number2.00 ms1.86 ms1.65 ms ✅
⇒ Load + parse first number9.82 ms ✅16.14 ms16.18 ms
Format again0.09 ms ✅0.22 ms0.13 ms
Parse again0.39 ms ✅0.51 ms0.43 ms
Increased memory usage9.77 M ✅12.71 M11.25 M
node_modules size720 K* 604 K ✅9.9 M
node_modules files9* 7 ✅787

* NOTE: google-libphonenumber only ships CJS, while awesome-phonenumber and libphonenumber-js ships both CJS and ESM

Basic usage

import { parsePhoneNumber } from 'awesome-phonenumber'

const pn = parsePhoneNumber( '0707123456', { regionCode: 'SE' } );
// or on e164 format:
const pn = parsePhoneNumber( '+46707123456' );

// pn is now the same as:
const pn = {
	valid: true,

	number: {
		input: '0707123456',
		e164: '+46707123456',
		international: '+46 70 712 34 56',
		national: '070-712 34 56',
		rfc3966: 'tel:+46-70-712-34-56',
		significant: '707123456',
	},
	possibility: 'is-possible',
	regionCode: 'SE',
	possible: true,
	shortPossible: false,
	shortValid: false,
	canBeInternationallyDialled: true,
	type: 'mobile',
	countryCode: 46,
	typeIsMobile: true,
	typeIsFixedLine: false,
};

The return type is ParsedPhoneNumber which is either a ParsedPhoneNumberValid or a ParsedPhoneNumberInvalid. The valid property identifies whether the parsing was successful or not, hence which type is returned.

The format of a successful parsing is:

interface ParsedPhoneNumberValid {
	valid: true;

	number: {
		input: string;
		international: string;
		national: string;
		e164: string;
		rfc3966: string;
		significant: string;
	};
	possibility: PhoneNumberPossibility; // a string union, see below
	regionCode: string;
	possible: boolean;
	shortPossible: boolean;
	shortValid: boolean;
	canBeInternationallyDialled: boolean;
	type: PhoneNumberTypes; // a string union, see below
	countryCode: number;
	typeIsMobile: boolean;
	typeIsFixedLine: boolean;
}

If the number failed to be parsed, or there was another error, the return type is:

interface ParsedPhoneNumberInvalid {
	valid: false;

	possible: false;
	possibility: 'invalid';
	shortPossible: boolean;
	shortValid: boolean;
	error?: unknown;
};

Note that an incorrect (invalid) phone number can still be a valid short number for the given region.

API

import {
	parsePhoneNumber,
	findNumbers,
	getNumberFrom,
	getExample,
	getCountryCodeForRegionCode,
	getRegionCodeForCountryCode,
	getSupportedCallingCodes,
	getSupportedRegionCodes,
	getAsYouType,
} from 'awesome-phonenumber'

parsePhoneNumber

parsePhoneNumber( phoneNumber, { regionCode: string } ) parses a phone number as described above.

The first argument is the phone number to parse, on either national or international (e164, i.e. prefixed with a +) form. If national form, the second argument is required to contain a regionCode string property, e.g. 'SE' for Sweden, 'CH' for Switzerland, etc.

findNumbers

To find (extract) phone numbers in text, use findNumbers( ):

import { findNumbers } from 'awesome-phonenumber'

const text = 'My number is +46 707 123 456, otherwise call +33777777777.';
const numbers = findNumbers( text );

The returned list of numbers is of the type PhoneNumberMatch such as:

interface PhoneNumberMatch
{
	text: string; // The raw string found
	phoneNumber: object; // Same as the result of parsePhoneNumber()
	start: number; // Start offset in the text
	end: number; // End offset in the text
}

A second options argument to findNumbers( text, options ) can be provided on the form:

interface FindNumbersOptions
{
	defaultRegionCode?: string;
	leniency?: FindNumbersLeniency;
	maxTries?: number;
}

where FindNumbersLeniency is an enum of 'valid' or 'possible'. The default is 'valid' meaning that only valid phone numbers are found. If this is set to 'possible' also possible (but invalid) phone numbers are found.

defaultRegionCode can be set (e.g. to 'SE' for Sweden), in which case phone numbers on national form (i.e. without + prefix) will be found, as long as they are from that region.

For really large texts, maxTries will set the maximum number of phone numbers to try to find (not necessary actually find).

getNumberFrom

import { parsePhoneNumber, getNumberFrom } from 'awesome-phonenumber'

const pn = parsePhoneNumber( '0707654321', { regionCode: 'SE' } );
if ( pn.valid ) {
	const fromJp = getNumberFrom( pn, 'JP' );
	// fromJp is the number to call from Japan:
	fromJp.number === "010 46 70 765 43 21";
}

The return value from getNumberFrom is a PhoneNumberFrom which is either a PhoneNumberFromValid or a PhoneNumberFromInvalid.

The PhoneNumberFromValid is defined as:

interface PhoneNumberFromValid
{
	valid: true;
	number: string;
}

The PhoneNumberFromInvalid is defined as:

interface PhoneNumberFromInvalid
{
	valid: false;
	error?: unknown;
}

getExample

Sometimes you want to display a formatted example phone number for a certain country (and maybe also a certain type of phone number). The getExample function is used for this.

import { getExample } from 'awesome-phonenumber'

getExample( regionCode[, phoneNumberType] ); // Parsed phone number

The phoneNumberType is any of the types defined above.

Example

import { getExample } from 'awesome-phonenumber'

// Get an example Swedish phone number
const example = getExample( 'SE' ); // A ParsedPhoneNumberValid
const exampleMobile = getExample( 'SE', 'mobile' ); // A ParsedPhoneNumberValid

example.number.e164;           // e.g. '+468123456'
exampleMobile.number.e164;     // e.g. '+46701234567'
exampleMobile.number.national; // e.g. '070 123 45 67'

Country codes

There are conversion functions between the 2-character ISO 3166-1 region codes (e.g. 'SE' for Sweden) and the corresponding country calling codes.

import {
	getCountryCodeForRegionCode,
	getRegionCodeForCountryCode,
	getSupportedCallingCodes,
	getSupportedRegionCodes,
} from 'awesome-phonenumber'

getCountryCodeForRegionCode( regionCode );  // -> countryCode
getRegionCodeForCountryCode( countryCode ); // -> regionCode

Example

getCountryCodeForRegionCode( 'SE' ); // -> 46
getRegionCodeForCountryCode( 46 );   // -> 'SE'

Supported calling codes

getSupportedCallingCodes( ); // -> [ calling codes... ]

Supported region codes

getSupportedRegionCodes( ); // -> [ region codes... ]

API types

The API consists of the PhoneNumber class which sometimes uses enums. These are:

Phone number types

type PhoneNumberTypes =
	| 'fixed-line'
	| 'fixed-line-or-mobile'
	| 'mobile'
	| 'pager'
	| 'personal-number'
	| 'premium-rate'
	| 'shared-cost'
	| 'toll-free'
	| 'uan'
	| 'voip'
	| 'unknown'

Phone number possibilities

type PhoneNumberPossibility =
	| 'is-possible'
	| 'invalid-country-code'
	| 'too-long'
	| 'too-short'
	| 'unknown'

Phone number formats

'international'
'national'
'e164'
'rfc3966'
'significant'

As-you-type formatting

You can create an AsYouType class with getAsYouType() to format a phone number as it is being typed.

import { getAsYouType } from 'awesome-phonenumber'

const ayt = getAsYouType( 'SE' );

The returned class instance has the following methods

// Add a character to the end of the number
ayt.addChar( nextChar: string );

// Get the current formatted number
ayt.number( );

// Remove the last character
ayt.removeChar( );

// Replace the whole number with a new number (or an empty number if undefined)
ayt.reset( number?: string );

// Get a ParsedPhoneNumber object representing the current number
ayt.getPhoneNumber( );

All the functions above except getPhoneNumber( ) return the current formatted number as a string.

Example

import { getAsYouType } from 'awesome-phonenumber'

const ayt = getAsYouType( 'SE' );
ayt.addChar( '0' ); // -> '0'
ayt.addChar( '7' ); // -> '07'
ayt.addChar( '0' ); // -> '070'
ayt.addChar( '7' ); // -> '070 7'
ayt.addChar( '1' ); // -> '070 71'
ayt.addChar( '2' ); // -> '070 712'
ayt.addChar( '3' ); // -> '070 712 3'
ayt.addChar( '4' ); // -> '070 712 34'
ayt.addChar( '5' ); // -> '070 712 34 5'
ayt.addChar( '6' ); // -> '070 712 34 56'
ayt.removeChar( );  // -> '070 712 34 5'
ayt.addChar( '7' ); // -> '070 712 34 57'