Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

libphonenumber-js

catamphetamine35.3mMIT1.12.22TypeScript support: included

A simpler (and smaller) rewrite of Google Android's libphonenumber library in javascript

telephone, phone, number, input, mobile, libphonenumber

readme

libphonenumber-js

npm version npm downloads

A simpler and smaller rewrite of Google Android's libphonenumber library in javascript/TypeScript.

Parse and format personal phone numbers.

See Demo

If you’re trying to build a React component with it, take a look at react-phone-number-input.

LibPhoneNumber

Google's libphonenumber is an ultimate phone number formatting and parsing library developed by Google for Android phones. It is written in C++ and Java, and, while it has an official autogenerated javascript port, that port is tightly coupled to Google's closure javascript framework, and, when compiled into a bundle, weighs about 550 kB (350 kB code + 200 kB metadata).

With many websites today asking for user's phone number, the internet could benefit from a simpler and smaller library that would just deal with parsing or formatting personal phone numbers, and that's what libphonenumber-js is.

Differences from Google's libphonenumber

  • Smaller footprint: 145 kB (65 kB code + 80 kB sufficient metadata) vs the original Google's 550 kB (350 kB code + 200 kB full metadata).

  • Can search for phone numbers in text. Google's autogenerated javascript port doesn't provide such feature for some reason.

  • Focuses on parsing and formatting personal phone numbers while skipping any other "special" cases like:

    • Emergency phone numbers like 911.

    • "Short codes" — short SMS-only numbers like 12345.

    • Numbers starting with an *. For example, *555 is used in New Zeland to report non-urgent traffic incidents. Or, in Israel, certain advertising numbers start with a *.

    • Australian 13-smart numbers, which are a "catchy" "short" form of regular "landline" numbers and are mainly used in advertisement.

    • Alphabetic phone numbers like 1-800-GOT-MILK. People don't input their phone numbers like that. It was only used in advertisement in the days of push-button telephones.

    • "Two-in-one" phone numbers with "combined" extensions like (530) 583-6985 x302/x2303. Phone numbers like that actually represent two separate phone numbers, so it's not clear which one to pick or how to return both at the same time.

    • Local numbers with the "area code" omitted. For example, when dialing phone numbers within the same "area", people sometimes skip the "area code", and dial, say, just 456-789 instead of proper (123) 456-789. This all is considered a relic of the past. In the modern world, there're no "local areas" and anyone could call everyone else around the world.

  • Doesn't provide "geolocation" feature when it can tell a city by a phone number.

  • Doesn't use hyphens or brackets when formatting phone numbers in international format. Instead, whitespace is used. The rationale is that brackets aren't relevant in international context because there're no "local areas", and hyphens aren't used because whitespace just looks cleaner.

  • Doesn't set .country to "001" when parsing "non-geographic" phone numbers, like mobile satellite communications services. Instead, .country is set to undefined in those cases, and instead a developer can call .isNonGeographic() method of the PhoneNumber instance to find out whether the parsed phone number is a "non-geographic" one.

  • Doesn't provide the equivalent of libphonenumber's formatNumberForMobileDialing() function that formats a number for dialing from a mobile phone within the same country. This feature may be required for dialing local numbers from a mobile phone in some countries like Brazil or Colombia where they require adding "carrier codes" when making such calls. Since libphonenumber-js is not a dialing library (we're not Android phone operaing system), it doesn't prepend any "carrier codes" when formatting such phone numbers, though it does parse such "carrier codes" correctly.

  • Fixed a small bug when Canadian numbers +1310xxxx wheren't considered possible.

    <!--

  • Doesn't use "carrier codes" when formatting numbers: "carrier codes" are only used in Colombia and Brazil and only when dialing within those countries from a mobile phone to a fixed line number. (.formatNumberForMobileDialing() method is not implemented therefore there's no need to format carrier codes) -->

GitHub Repository Status

On March 9th, 2020, GitHub, Inc. silently banned my account — erasing all my repos, issues and comments, even in my employer's private repos — without any notice or explanation. Because of that, all source codes had to be promptly moved to GitLab. The GitHub repo is now only used as a backup (although you can still "star" it), and the primary repo is now the GitLab one. For users' convenience, issues can be reported in both places.

Install

via npm

$ npm install libphonenumber-js --save

via yarn

$ yarn add libphonenumber-js

Alternatively, one could include it on a web page directly via a <script/> tag.

Use

If you'd like to create an issue, see bug reporting instructions.

Parse phone number

Parses a complete phone number.

import parsePhoneNumber from 'libphonenumber-js'

const phoneNumber = parsePhoneNumber(' 8 (800) 555-35-35 ', 'RU')

if (phoneNumber) {
  phoneNumber.country === 'RU'
  phoneNumber.number === '+78005553535'
  phoneNumber.isPossible() === true
  phoneNumber.isValid() === true
  // Note: `.getType()` requires `/max` metadata: see below for an explanation.
  phoneNumber.getType() === 'TOLL_FREE'
}

Format phone number

Formats a complete phone number.

import parsePhoneNumber from 'libphonenumber-js'

const phoneNumber = parsePhoneNumber('+12133734253')

if (phoneNumber) {
  phoneNumber.formatInternational() === '+1 213 373 4253'
  phoneNumber.formatNational() === '(213) 373-4253'
  phoneNumber.getURI() === 'tel:+12133734253'
}

"As You Type" formatter

Parses and formats an incomplete phone number.

import { AsYouType } from 'libphonenumber-js'

new AsYouType().input('+12133734')
// Returns: '+1 213 373 4'

new AsYouType('US').input('2133734')
// Returns: '(213) 373-4'

Validate phone number

Validates a complete phone number.

import {
  isPossiblePhoneNumber,
  isValidPhoneNumber,
  validatePhoneNumberLength
} from 'libphonenumber-js'

isPossiblePhoneNumber('8 (800) 555-35-35', 'RU') === true
isValidPhoneNumber('8 (800) 555-35-35', 'RU') === true

validatePhoneNumberLength('8 (800) 555', 'RU') === 'TOO_SHORT'
validatePhoneNumberLength('8 (800) 555-35-35', 'RU') === undefined // Length is valid.

isPossiblePhoneNumber() only validates phone number length, while isValidPhoneNumber() validates both phone number length and phone number digits.

validatePhoneNumberLength() is just a more detailed version of isPossiblePhoneNumber() — if the phone number length is invalid, instead of just returning false, it returns the actual reason why the phone number length is incorrect: TOO_SHORT, TOO_LONG, etc.

Finds complete phone numbers in text.

import { findPhoneNumbersInText } from 'libphonenumber-js'

findPhoneNumbersInText(`
  For tech support call +7 (800) 555-35-35 internationally
  or reach a local US branch at (213) 373-4253 ext. 1234.
`, 'US')

// Outputs:
//
// [{
//   number: PhoneNumber {
//     country: 'RU',
//     countryCallingCode: '7',
//     number: '+78005553535',
//     nationalNumber: '8005553535'
//   },
//   startsAt : 22,
//   endsAt   : 40
// }, {
//   number: PhoneNumber {
//     country: 'US',
//     countryCallingCode: '1',
//     number: '+12133734253',
//     nationalNumber: '2133734253',
//     ext: '1234'
//   },
//   startsAt : 86,
//   endsAt   : 110
// }]

"min" vs "max" vs "mobile" vs "core"

This library provides different "metadata" sets, where a "metadata" set is a complete list of phone number parsing and formatting rules for all possible countries.

As one may guess, the complete list of those rules is huge, so this library provides a way to optimize bundle size by choosing between max, min, mobile or "custom" metadata:

  • min — (default) The smallest metadata set

    • Is about 80 kilobytes in size (libphonenumber-js/metadata.min.json file)
    • Choose this when:
      • You don't need to detect phone number type — "fixed line", "mobile", etc — via .getType()
      • You're fine with just validating phone number length via .isPossible() and you don't need to strictly validate phone number digits via .isValid()
  • max — The complete metadata set

    • Is about 145 kilobytes in size (libphonenumber-js/metadata.max.json file)
    • Choose this when:
      • The basic .isPossible() phone number length check is not enough for you and you need the strict phone number digits validation via .isValid()
      • You need to detect phone number type — "fixed line", "mobile", etc — via .getType()
  • mobile — The complete metadata set for dealing with mobile numbers only

    • Is about 95 kilobytes in size (libphonenumber-js/metadata.mobile.json file)
    • Choose this when:
      • You need max metadata capabilities and you only accept mobile numbers
        • It will still be able to handle non-mobile numbers just fine, with the only difference that .isValid() or .isPossible() might potentially return false for them, or .getType() might potentially return undefined.

Choose one from the above and then simply import the functions from the relevant sub-package:

  • minlibphonenumber-js/min, or just libphonenumber-js, since it's the default.
  • maxlibphonenumber-js/max
  • mobilelibphonenumber-js/mobile

As for "custom" metadata, it could be used in those rare cases when not all countries are needed and a developer would really prefer to reduce the bundle size to a minimum. In that case, one could generate their own "custom" metadata set and then import the functions from libphonenumber-js/core sub-package which doesn't come pre-packaged with any metadata and instead accepts metadata as the last argument of each exported function.

Definitions

Country code

A "country code" is a two-letter ISO country code (like "US").

This library supports all officially assigned ISO alpha-2 country codes, plus a few extra ones: AC (Ascension Island), TA (Tristan da Cunha), XK (Kosovo).

To check whether a country code is supported, use isSupportedCountry() function.

Non-geographic

There're several calling codes that don't belong to any country:

Such phone numbering plans are called "non-geographic", and their phone numbers' country is undefined.

National (significant) number

"National (significant) number" is all national phone number digits, excluding the "national prefix". Examples:

  • International number: +1 213 373 4253. Country: "US". National number: (213) 373-4253. National (significant) number: 213 373 4253
  • Inetrnational number: +33 1 45 45 32 45. Country: "FR". National number: 01 45 45 32 45. Notice the 0 at the start of the national number — it's because in France they add 0 "national prefix" when writing phone numbers in national format. National (significant) number: 1 45 45 32 45 (doesn't include the "national prefix").

Country calling code

"Country calling code" is all digits between the + and the national (significant) number in a number that is written in international format. Examples:

  • International number: +1 213 373 4253. Country: "US". National (significant) number: 213 373 4253. Country calling code: 1
  • Inetrnational number: +33 1 45 45 32 45. Country: "FR". National (significant) number: 1 45 45 32 45. Country calling code: 33

Several countries could share the same "country calling code". For example, NANPA countries like USA and Canada share the same 1 country calling code.

API

parsePhoneNumber(string, defaultCountry?: string | options?: object): PhoneNumber

Parses a complete phone number from string.

Can be imported either as a "default" export or as a "named" export called parsePhoneNumberFromString.

import parsePhoneNumber from 'libphonenumber-js'
// import { parsePhoneNumberFromString as parsePhoneNumber } from 'libphonenumber-js'

const phoneNumber = parsePhoneNumber('(213) 373-42-53 ext. 1234', 'US')
if (phoneNumber) {
  console.log(phoneNumber.formatNational())
}

Returns an instance of PhoneNumber class, or undefined if no phone number could be parsed from the input string. That could be for a number of reasons. For example, the phone number in the input string could be incomplete, or it could contain a phone number that has an invalid country calling code, etc.

Available options:

  • defaultCountry: string — Default country for parsing numbers written in non-international form (without a + sign). Will be ignored when parsing numbers written in international form (with a + sign). Instead of passing it as options.defaultCountry, one could also pass it as a standalone defaultCountry argument (for convenience).

  • defaultCallingCode: string — Default calling code for parsing numbers written in non-international form (without a + sign). Will be ignored when parsing numbers written in international form (with a + sign). It could be specified when parsing phone numbers belonging to "non-geographic numbering plans" which by nature don't have a country code, making the defaultCountry option unusable.

  • extract: boolean — Defines the "strictness" of parsing a phone number. By default, the extract flag is true meaning that it will attempt to extract the phone number from an input string like "My phone number is (213) 373-4253 and my hair is blue". This could be thought of as "less strict" parsing. To make it "more strict", one could pass extract: false flag, in which case the function will attempt to parse the input string as if the whole string was a phone number. Applied to the example above, it would return undefined because the entire string is not a phone number, but for an input string "(213) 373-4253" it would return a parsed PhoneNumber.

If a developer wants to know the exact reason why the phone number couldn't be parsed then they can use parsePhoneNumberWithError() function which throws an exact error:

import { parsePhoneNumberWithError, ParseError } from 'libphonenumber-js'

try {
  const phoneNumber = parsePhoneNumberWithError('(213) 373-42-53 ext. 1234', {
    defaultCountry: 'US'
  })
} catch (error) {
  if (error instanceof ParseError) {
    // Not a phone number, non-existent country, etc.
    console.log(error.message)
  } else {
    throw error
  }
}
<summary>Possible errors</summary>
  • NOT_A_NUMBER — When the supplied string is not a phone number. For example, when there are no digits: "abcde", "+".

  • INVALID_COUNTRY

    • When defaultCountry doesn't exist (or isn't supported by this library yet): parsePhoneNumber('(111) 222-3333', 'XX').
    • When parsing a non-international number without a defaultCountry: parsePhoneNumber('(111) 222-3333').
    • When an international number's country calling code doesn't exist: parsePhoneNumber('+9991112223333').
  • TOO_SHORT — When the number is too short. For example, just 1 or 2 digits: "1", "+12".

  • TOO_LONG — When the national (significant) number is too long (17 digits max) or when the string being parsed is too long (250 characters max).

Strictness

By default, the parsing function will attempt to extract a phone number from the input string even in cases like "Support: (213) 373-4253 (robot)", which mimicks the behavior of the original Google's libphonenumber library, and is the default behavior for legacy reasons. However, if "strict" input validation is required, one can pass extract: false flag to demand that the whole input string be a viable phone number.

// By default it parses without `extract: false` flag.
// It will "extract" the phone number from the input string.
parsePhoneNumber('Call: (213) 373-4253', 'US') === PhoneNumber

// When parsing the same input string with `extract: false` flag,
// it will return `undefined`, because a phone number can't
// contain letters or a colon.
parsePhoneNumber('Call: (213) 373-4253', {
  defaultCountry: 'US',
  extract: false
}) === undefined

// When the whole input string represents a phone number,
// parsing it with `extract: false` flag will return a `PhoneNumber`.
parsePhoneNumber('(213) 373-4253', {
  defaultCountry: 'US',
  extract: false
}) === PhoneNumber

PhoneNumber

PhoneNumber class represents a complete phone number.

PhoneNumber class instance is returned from parsePhoneNumber() function, or it could also be constructed manually from a number in E.164 format:

const phoneNumber = new PhoneNumber('+12133734253')

// (optional) Add a phone number extension.
phoneNumber.setExt('1234')

PhoneNumber class instance has the following properties:

  • number: string — The phone number in E.164 format. Example: "+12133734253".
  • countryCallingCode: string — The country calling code. Example: "1".
  • nationalNumber: string — The national (significant) number. Example: "2133734253".
  • country: string? — The country code. Example: "US". Will be undefined when no country could be derived from the phone number. For example, when several countries have the same countryCallingCode and the nationalNumber doesn't look like it belongs to any particular one of them. Or when a number belongs to a non-geographic numbering plan.
  • ext: string? — The phone number extension, if any. Example: "1234".
  • carrierCode: string? — The "carrier code", if any. Example: "15". "Carrier codes" are only used in Colombia and Brazil and only when dialing within those countries from a mobile phone to a fixed line number.

PhoneNumber class instance provides the following methods:

setExt(ext: string)

Adds a phone number extension to a phone number.

const phone = "+12133734253"
const phoneExt = "1234"

const phoneNumber = parsePhoneNumber(phone)
if (phoneNumber) {
  if (phoneExt) {
    phoneNumber.setExt(phoneExt)
  }
  // Returns "(213) 373-4253 ext. 1234"
  return phoneNumber.formatNational()
}

format(format: string, [options]): string

Formats the phone number into a string according to a specified format.

Available formats:

  • NATIONAL — Example: "(213) 373-4253"
  • INTERNATIONAL — Example: "+1 213 373 4253"
  • E.164 — Example: "+12133734253"
  • RFC3966 (the phone number URI) — Example: "tel:+12133734253;ext=123"
  • IDD"Out-of-country" dialing format. Example: "011 7 800 555 35 35" for +7 800 555 35 35 being called out of options.fromCountry === "US". If no options.fromCountry was passed or if there's no default IDD prefix for options.fromCountry then returns undefined.

Available options:

  • formatExtension(number, extension) — Formats number and extension into a string. By default returns ${number} ext. ${extension} for almost all countries with rare exceptions of some special cases like ${number} x${extension} for the United Kingdom.

  • nationalPrefix: Boolean — Some phone numbers can be formatted both with national prefix and without it. In such cases the library defaults to "with national prefix" (for legacy reasons). Pass nationalPrefix: false option to force formatting without a national prefix.

Examples:

import parsePhoneNumber from 'libphonenumber-js'

const phoneNumber = parsePhoneNumber('+12133734253')

phoneNumber.format("NATIONAL") === '(213) 373-4253'
phoneNumber.format("INTERNATIONAL") === '+1 213 373 4253'
phoneNumber.format("RFC3966") === 'tel:+12133734253'

// The following are just convenience aliases for the `.format()` function.
phoneNumber.formatNational() === phoneNumber.format("NATIONAL")
phoneNumber.formatInternational() === phoneNumber.format("INTERNATIONAL")
phoneNumber.getURI() === phoneNumber.format("RFC3966")

isPossible(): boolean

Checks if the phone number is "possible". Only checks the phone number length. Doesn't check the actual phone number digits.

isValid(): boolean

Checks if the phone number is "valid". First checks the phone number length and then checks the phone number digits against all available regular expressions.

By default, this library uses min ("minimal") metadata which is only 80 kB in size but also doesn't include the precise validation regular expressions resulting in less strict validation rules (some very basic validation like number length check is still included for each country). If you don't mind the extra 65 kB of metadata then use max metadata instead of the default (min) one. Google's library always uses "full" metadata so it will yield different isValidNumber() results compared to the "minimal" metadata used by default in this library.

<summary>See an example illustrating different results when using /min vs /max vs /mobile metadata</summary>

#

import parseMin from 'libphonenumber-js/min'
import parseMax from 'libphonenumber-js/max'
import parseMobile from 'libphonenumber-js/mobile'

// In Singapore (+65), when a mobile number starts with `8`,
// it can only have the second digit in the range of `0..8`.
// In a number "+6589555555", the second digit is `9`
// which makes it an invalid mobile number.
// This is a "strict" validation rule and it is
// not included in the (default) `min` metadata.

// When using the (default) `min` metadata,
// basic number length check passes (from `8` to `11`)
// and the "loose" national number validation regexp check passes too:
// `(?:1\d{3}|[369]|7000|8(?:\d{2})?)\d{7}`.
parseMin('+6589555555').isValid() === true

// When using `max` or `mobile` metadata,
// the validation regexp for mobile numbers is more precise —
// `(?:8[1-8]|9[0-8])\\d{6}` — as well as the possible lengths (only `8`).
parseMax('+6589555555').isValid() === false
parseMobile('+6589555555').isValid() === false

#

See "Using phone number validation feature" for choosing between isPossible() and isValid().

getPossibleCountries(): string[]

Returns a list of countries that this phone number could possibly belong to.

Can be used when parsing a complete international phone number which contains a "country calling code" that is shared between several countries. If parsing such a phone number returns country: undefined then getPossibleCountries() function could be used to somehow speculate about what country could this phone number possibly belong to.

getType(): string?

Returns phone number type — fixed line, mobile, toll free, etc — or undefined if the number is invalid or if there are no phone number type regular expressions for this country in metadata.

By default, this library uses min ("minimal") metadata which is only 80 kB in size but also doesn't include the regular expressions for determining a phone number type — fixed line, mobile, toll free, etc — which could result in getType() returning undefined for most countries. If you don't mind the extra 65 kB of metadata then use max metadata instead of the default (min) one. Google's library always uses "full" metadata so it will yield different getNumberType() results compared to the "minimal" metadata used by default in this library.

<summary>The list of possible return values</summary>

#

  • MOBILE — Cellphones.
  • FIXED_LINE — Stationary phones.
  • FIXED_LINE_OR_MOBILE — Could be MOBILE or FIXED_LINE.
  • PREMIUM_RATE — Callers are charged by call or per minute. SMS text messages are also subject to charge.
  • TOLL_FREE — Free to call from anywhere.
  • SHARED_COST — "An intermediate level of telephone call billing where the charge for calling a particular international or long-distance phone number is partially, but not entirely, paid for by the recipient".
  • VOIP — "IP telephony". Calls are made over the Internet rather than via the conventional telephone-only lines.
  • PERSONAL_NUMBER — Phones connected by satellites.
  • PAGER — "Pagers" are wireless telecommunications devices that were widely used in the 80-es and could receive (and, optionally, send) text or voice messages.
  • UAN — "UAN is a number resource that allows a service or business with several terminating lines to be reached through a unique universal number. A UAN number shall be dialable from the entire Pakistan, based on the applicant’s proposed coverage without dialing the area code. UAN cannot be assigned to two separate business or mutually exclusive public services. Each service provider who allows UAN through its network shall offer a tariff, which is not more expensive than the normal tariff available for a similar non-UAN public service".
  • VOICEMAIL — "A voicemail access number is a telephone number provided by a voicemail service to allow subscribers to dial into their voicemail accounts and manage any currently saved messages. Typically, the number is used when a subscriber is away from home and wishes to check any voice messages currently stored on the service. Originally envisioned as part of the features associated with voicemail accounts offered with land line accounts, many mobile service providers today also supply their customers with a voicemail access number to use when checking messages from any phone other than the mobile or cellular unit associated with the account".

#

<summary>See an example illustrating different results when using /min vs /max vs /mobile metadata</summary>

#

import parseMin from 'libphonenumber-js/min'
import parseMax from 'libphonenumber-js/max'
import parseMobile from 'libphonenumber-js/mobile'

// Singapore (+65) mobile number "+6584655555".

// The (default) `min` bundle doesn't contain any regexps for
// getting phone number type from phone number digits for Singapore.
parseMin('+6584655555').getType() === undefined

// The `max` does contain all the regexps for getting
// phone number type from phone number digits for any country.
parseMax('+6584655555').getType() === 'MOBILE'


// The `max` does contain all the regexps for getting
// mobile phone number type from mobile phone number digits for any country.
parseMobile('+6584655555').getType() === 'MOBILE'

isNonGeographic(): boolean

Returns true if the number belongs to a "non-geographic numbering plan".

isEqual(phoneNumber: PhoneNumber): boolean

Compares two PhoneNumbers: returns true if they're equal, false otherwise.

isPossiblePhoneNumber(input: string, defaultCountry?: string | options?: object): boolean

Checks if input can be parsed as a "possible" phone number. A phone number is "possible" when it has valid length. The actual phone number digits aren't validated.

isPossiblePhoneNumber('8 (888) 888-88-88', 'RU') === true
isPossiblePhoneNumber('+12223333333') === true

For the description of the defaultCountry?: string | options?: object argument, see parsePhoneNumber() function description.

This function is just a shortcut for a two-step process of "strictly" parsing a phone number and then calling .isPossible().

isValidPhoneNumber(input: string, defaultCountry?: string | options?: object): boolean

Checks if input can be parsed as a "valid" phone number. A phone number is "valid" when it has valid length, and the actual phone number digits match the regular expressions for its country.

isValidPhoneNumber('8 (888) 888-88-88', 'RU') === false
isValidPhoneNumber('8 (800) 555-35-35', 'RU') === true
isValidPhoneNumber('+12223333333') === false
isValidPhoneNumber('+12133734253') === true

For the description of the defaultCountry?: string | options?: object argument, see parsePhoneNumber() function description.

This function is just a shortcut for a two-step process of "strictly" parsing a phone number and then calling .isValid().

See "Using phone number validation feature" for choosing between isPossible() and isValid().

isValidPhoneNumberForCountry(input: string, country: string): boolean

Same as isValidPhoneNumber() but with the "default country" argument being replaced with an "exact country", which is more strict.

This function is not currently exported from this library. The reason is that its result would be too vague when it returns false — it could mean any of:

  • The input is not a valid phone number.
  • The input is a valid phone number but it belongs to another country.
  • The input is a phone number that belongs to the correct country but is not valid.

At least the second case should be handled separately from a "User Experience" point of view: if the user has input a valid phone number but for another country, they should be notified that "perhaps you meant another country" rather than just throwing "the phone number is incorrect" error in their face.

But for those who'd still like to have such function, here's a possible implementation for it:

export default function isValidPhoneNumberForCountry(phoneNumberString, country) {
  const phoneNumber = parsePhoneNumber(phoneNumberString, {
    defaultCountry: country,
    // Demand that the entire input string must be a phone number.
    // Otherwise, it would "extract" a phone number from an input string.
    extract: false
  })
  if (!phoneNumber) {
    return false
  }
  if (phoneNumber.country !== country) {
    return false
  }
  return phoneNumber.isValid()
}

The same approach could be used to implement an isPossiblePhoneNumberForCountry() function.

validatePhoneNumberLength(input: string, defaultCountry?: string | options?: object): string?

Checks if input phone number length is valid. If it is, then nothing is returned. Otherwise, a rejection reason is returned.

<summary>Possible rejection reasons</summary>
  • NOT_A_NUMBER — When the supplied string is not a phone number. For example, when there are no digits: "abcde", "+".

  • INVALID_COUNTRY

    • When defaultCountry doesn't exist (or isn't supported by this library yet): parsePhoneNumber('(111) 222-3333', 'XX').
    • When parsing a non-international number without a defaultCountry: parsePhoneNumber('(111) 222-3333').
    • When an international number's country calling code doesn't exist: parsePhoneNumber('+9991112223333').
  • TOO_SHORT — When the number is too short. For example, just 1 or 2 digits: "1", "+12".

  • TOO_LONG — When the national (significant) number is too long (17 digits max) or when the string being parsed is too long (250 characters max).

  • INVALID_LENGTH — When the national (significant) number is neither too short, nor too long, but somewhere in between and its length is still invalid.

#
validatePhoneNumberLength('abcde') === 'NOT_A_NUMBER'
validatePhoneNumberLength('444 1 44') === 'INVALID_COUNTRY'
validatePhoneNumberLength('444 1 44', 'TR') === 'TOO_SHORT'
validatePhoneNumberLength('444 1 444', 'TR') === undefined // Length is valid.
validatePhoneNumberLength('444 1 4444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 44444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 444444', 'TR') === undefined // Length is valid.
validatePhoneNumberLength('444 1 4444444444', 'TR') === 'TOO_LONG'

For the description of the defaultCountry?: string | options?: object argument, see parsePhoneNumber() function description.

This function is just a more detailed version of isPossiblePhoneNumber() for those who asked for a more specific rejection reason.

The phone number is parsed "strictly" from the input string.

class AsYouType(defaultCountry?: string | options?: object)

Creates a formatter for a partially-entered phone number.

For the description of the defaultCountry?: string | options?: object argument, see parsePhoneNumber() function description.

The formatter instance has the following methods:

  • input(text: string) — Appends text to the input. Returns the formatted phone number.

  • reset() — Resets the input.

new AsYouType().input('+12133734') === '+1 213 373 4'
new AsYouType('US').input('2133734') === '(213) 373-4'

The formatter instance also provides the following getters:

  • getNumber(): PhoneNumber? — Returns the PhoneNumber. Will return undefined if no national (significant) number digits have been entered so far, or if no defaultCountry/defaultCallingCode has been specified and the user enters a phone number in national format (without a +).

  • getNumberValue(): string? — Returns the phone number in E.164 format. For example, for default country "US" and input "(222) 333-4444" it will return "+12223334444". Will return undefined if no digits have been input, or when the user inputs a phone number in national format (without a +) and no default country or default "country calling code" have been specified.

  • getChars(): string — Returns the phone number characters: + sign (if present) and the digits. Returns an empty string if no phone number characters have been input.

  • getTemplate(): string — Returns the template that is used to format the phone number characters — + sign (if present) and the digits — which are designated by x-es. Returns an empty string if no phone number characters have been input.

// National phone number input example.

const asYouType = new AsYouType('US')

asYouType.input('2') === '2'
asYouType.getNumber().number === '+12'
asYouType.getChars() === '2'
asYouType.getTemplate() === 'x'

asYouType.input('1') === '21'
asYouType.getNumber().number === '+121'
asYouType.getChars() === '21'
asYouType.getTemplate() === 'xx'

asYouType.input('3') === '(213)'
asYouType.getNumber().number === '+1213'
asYouType.getChars() === '213'
asYouType.getTemplate() === '(xxx)'

asYouType.input('3734253') === '(213) 373-4253'
asYouType.getNumber().number === '+12133734253'
asYouType.getChars() === '2133734253'
asYouType.getTemplate() === '(xxx) xxx-xxxx'

// International phone number input example.

const asYouType = new AsYouType()
asYouType.input('+1-213-373-4253') === '+1 213 373 4253'
asYouType.getNumber().country === 'US'
asYouType.getNumber().number === '+12133734253'
asYouType.getChars() === '+12133734253'
asYouType.getTemplate() === 'xx xxx xxx xxxx'
  • isInternational(): boolean — Returns true if the phone number is being input in international format. In other words, returns true if and only if the parsed phone number starts with a "+".

  • getCallingCode(): string? — Returns the "country calling code" part of the phone number. Returns undefined if the number is not being input in international format, or if no valid "country calling code" has been entered. Supports "non-geographic" phone numbering plans: even though those aren't technically "countries", they have their own "country calling codes" too.

  • getCountry(): string? — Returns a two-letter country code of the phone number. Returns undefined for "non-geographic" phone numbering plans. Returns undefined if no phone number has been input yet, or if it couldn't tell what country the phone number belongs to — that could happen when several countries have the same "country calling code" and the phone number doesn't look like it belongs to any particular one of them.

  • isPossible(): boolean — Returns true if the phone number is "possible". Is just a shortcut for getNumber()?.isPossible().

  • isValid(): boolean — Returns true if the phone number is "valid". Is just a shortcut for getNumber()?.isValid().

<summary>Legacy API (before version 1.6.0)</summary>

#

For legacy API (before version 1.6.0) the formatter instance provides the following getters:

  • country: string? — Phone number country. Will return undefined if the country couldn't be derived from the number.

  • getNationalNumber(): string — Returns the national (significant) number part of the phone number.

  • getTemplate(): string? — Same as the current version of getTemplate() with the only difference that it returns undefined if no suitable format was found for the number being entered (or if no national (significant) number has been entered so far).

// National phone number input example.

const asYouType = new AsYouType('US')

asYouType.input('2') === '2'
asYouType.getNationalNumber() === '2'

asYouType.input('1') === '21'
asYouType.getNationalNumber() === '21'

asYouType.input('3') === '(213)'
asYouType.getNationalNumber() === '213'

asYouType.input('3734253') === '(213) 373-4253'
asYouType.getNationalNumber() === '2133734253'

// International phone number input example.

const asYouType = new AsYouType()
asYouType.input('+1-213-373-4253') === '+1 213 373 4253'
asYouType.country === 'US'
asYouType.getNationalNumber() === '2133734253'

#

"As You Type" formatter was created by Google as part of their Android OS and therefore only works for numerical keyboard input, i.e. it can only accept digits (and a + sign at the start of an international number). When used on desktops where a user can input all kinds of punctuation (spaces, dashes, parens, etc) it simply ignores everything except digits (and a + sign at the start of an international number).

Google's "As You Type" formatter does not support entering phone number extensions. If your project requires inputting phone number extensions then use a separate input field for that.

findPhoneNumbersInText(text: string, defaultCountry?: string | options?: object): object[]

Searches for complete phone numbers in text.

Available options:

  • defaultCountry: string
  • defaultCallingCode: string

For the description of defaultCountry or defaultCallingCode, see parsePhoneNumber() function description.

import { findPhoneNumbersInText } from 'libphonenumber-js'

findPhoneNumbersInText(`
  For tech support call +7 (800) 555-35-35 internationally
  or reach a local US branch at (213) 373-4253 ext. 1234.
`, 'US')

// Outputs:
//
// [{
//   number: PhoneNumber {
//     country: 'RU',
//     countryCallingCode: '7',
//     number: '+78005553535',
//     nationalNumber: '8005553535'
//   },
//   startsAt : 22,
//   endsAt   : 40
// }, {
//   number: PhoneNumber {
//     country: 'US',
//     countryCallingCode: '1',
//     number: '+12133734253',
//     nationalNumber: '2133734253',
//     ext: '1234'
//   },
//   startsAt : 86,
//   endsAt   : 110
// }]

(in previous versions, it was called findNumbers())

<summary>Legacy API (before version 1.6.0) example</summary>

#

import { findNumbers } from 'libphonenumber-js'

findNumbers(`
  For tech support call +7 (800) 555-35-35 internationally
  or reach a local US branch at (213) 373-4253 ext. 1234.
`, 'US')

// Outputs:
//
// [{
//   phone    : '8005553535',
//   country  : 'RU',
//   startsAt : 22,
//   endsAt   : 40
// },
// {
//   phone    : '2133734253',
//   country  : 'US',
//   ext      : '1234',
//   startsAt : 86,
//   endsAt   : 110
// }]

#

By default it processes the whole text and then outputs the phone numbers found. If the text is very big (say, a hundred thousand characters) then it might freeze the user interface for a couple of seconds. To avoid such lags one could employ "iterator" approach using searchPhoneNumbersInText() to perform the search asynchronously (e.g. using requestIdleCallback or requestAnimationFrame).

(in previous versions, it was called searchNumbers())

<summary>Asynchronous search example using searchPhoneNumbersInText()</summary>

#

ES6 iterator:

import { searchPhoneNumbersInText } from 'libphonenumber-js'

const text = `
  For tech support call +7 (800) 555-35-35 internationally
  or reach a local US branch at (213) 373-4253 ext. 1234.
`

async function() {
  for (const number of searchPhoneNumbersInText(text, 'US')) {
    console.log(number)
    await new Promise(resolve => setTimeout(resolve, 0))
  }
  console.log('Finished')
}

Java-style iterator (for those still not using ES6):

import { PhoneNumberMatcher } from 'libphonenumber-js'

const matcher = new PhoneNumberMatcher(`
  For tech support call +7 (800) 555-35-35 internationally
  or reach a local US branch at (213) 373-4253 ext. 1234.
`, {
  defaultCountry: 'US',
  v2: true
})

// Search cycle iteration.
const iteration = () => {
  if (matcher.hasNext()) {
    console.log(matcher.next())
    setTimeout(iteration, 0)
  } else {
    console.log('Finished')
  }
}

// Run the search.
iteration()

#

Although Google's javascript port doesn't provide the findPhoneNumbersInText() function, the Java and C++ ports do. I guess that's because Google just doesn't need to crawl phone numbers on Node.js because they do it in Java or C++. Still, javascript nowadays is the most popular programming language given its simplicity and user-friendliness. The findPhoneNumbersInText() function provided by this library is a port of Google's PhoneNumberMatcher.java into javascript.

getExampleNumber(country: string, examples: object): PhoneNumber

Returns an example phone number for a country. Returns an instance of PhoneNumber class. Will return undefined if country doesn't exist or isn't supported by this library.

import examples from 'libphonenumber-js/mobile/examples'
import { getExampleNumber } from 'libphonenumber-js'

const phoneNumber = getExampleNumber('RU', examples)

phoneNumber.formatNational() === '8 (912) 345-67-89'

isSupportedCountry(country: string): boolean

Checks if a country is supported by this library.

isSupportedCountry('RU') === true
isSupportedCountry('XX') === false

getCountries(): string[]

Returns a list of supported countries.

getCountries() === ["AC", "AD", ...]

getCountryCallingCode(country: string): string

Returns country calling code for a country. Will throw an error if country doesn't exist or isn't supported by this library.

getCountryCallingCode('RU') === '7'
getCountryCallingCode('IL') === '972'

getExtPrefix(country: string): string

Returns phone number extension prefix for a given country. If no custom ext prefix is defined for a country then the default " ext. " prefix is returned.

getExtPrefix('US') === ' ext. '
getExtPrefix('GB') === ' x'

parseDigits(text: string): string

Parses digits from string. Can be used for building a phone number extension input component (e.g. react-phone-number-input).

parseDigits('x123') === '123'
parseDigits('٤٤٢٣') === '4423'

parseIncompletePhoneNumber(text: string): string

Parses phone number characters (+ and digits). Can be used for building a phone number input component (e.g. react-phone-number-input).

parseIncompletePhoneNumber('8 (800) 555') === '8800555'
parseIncompletePhoneNumber('+7 800 555') === '+7800555'
parseIncompletePhoneNumber('+٤٤٢٣٢٣٢٣٤') === '+442323234'

parsePhoneNumberCharacter(character, prevParsedCharacters?, eventListener?)

Parses next character of an input string while parsing phone number digits (including a +) from that string. Basically, it discards everything except + and digits, and + is only allowed at the start of a phone number.

This function is a low-level one that is currently only used in react-phone-number-input with input-format. Frankly speaking, that's the only reason why this function is exported. Other developers, perhaps, should just ignore it and use parseIncompletePhoneNumber() instead because it's much simpler.

// Suppose a user inputs a "+1 (213) 373-42-53" string
// and it starts parsing that string character-by-character.

parsePhoneNumberCharacter('+', undefined) === '+'
parsePhoneNumberCharacter('1', '+') === '1'
parsePhoneNumberCharacter(' ', '+1') === undefined
parsePhoneNumberCharacter('(', '+1') === undefined
parsePhoneNumberCharacter('2', '+1') === '2'
parsePhoneNumberCharacter('1', '+12') === '1'
parsePhoneNumberCharacter('3', '+121') === '3'
parsePhoneNumberCharacter(')', '+1213') === undefined
parsePhoneNumberCharacter(' ', '+1213') === undefined
parsePhoneNumberCharacter('3', '+1213') === '3'
parsePhoneNumberCharacter('7', '+12133') === '7'
parsePhoneNumberCharacter('3', '+121337') === '3'
parsePhoneNumberCharacter('-', '+121337') === undefined
parsePhoneNumberCharacter('4', '+1213373') === '4'
parsePhoneNumberCharacter('2', '+12133734') === '2'
parsePhoneNumberCharacter('-', '+12133734') === undefined
parsePhoneNumberCharacter('5', '+121337342') === '5'
parsePhoneNumberCharacter('3', '+1213373425') === '3'

So basically, it's the same as parseIncompletePhoneNumber() with the only difference that it operates at a character-by-character level rather than at a string-as-a-whole level.

The optional eventListener argument is a function of eventName: string argument. It will be called with an "end" argument in a situation when the application should stop parsing the input string. Currently, the only situation when that could happen is when it encounters an "out-of-place" + character. For example, when parsing a "+1 (234) + 56-78" string, it would emit an "end" event at the second + character so that the application could return "+1234" rather than "+12345678".

formatIncompletePhoneNumber(value: string, defaultCountry?: string | options?: object): string

Formats a possibly incomplete phone number.

While the usual parsePhoneNumber(string).format() function could only be used to format a complete phone number, this function could be used to format a possibly incomplete phone number.

The value argument should be a (possibly incomplete) phone number in E.164 format.

For the description of the defaultCountry?: string | options?: object argument, see parsePhoneNumber() function description.

This function is just an alias for new AsYouType(defaultCountry, metadata).input(value). It can be used for building a phone number input component (e.g. react-phone-number-input).

// National numbers, with second argument.
formatIncompletePhoneNumber('8800555', 'RU') === '8 (800) 555'
formatIncompletePhoneNumber('8800555', { defaultCountry: 'RU' }) === '8 (800) 555'
formatIncompletePhoneNumber('8800555', { defaultCallingCode: '7' }) === '8 (800) 555'

// International numbers, without second argument.
formatIncompletePhoneNumber('+7800555') === '+7 800 555'

Legacy API

<summary>Legacy API (before version 1.6.0): parse(), parseNumber(), format(), formatNumber(), isValidNumber(), getNumberType().</summary>

parseNumber(text, [defaultCountry], [options])

(previously called parse())

(legacy API)

Attempts to parse a phone number from text.

If defaultCountry is passed then it's gonna be the default country for parsing non-international phone numbers.

Returns { country, phone, ext } object where

If the phone number supplied isn't valid then an empty object {} is returned.

<summary>Examples</summary>
// Parses international numbers.
parseNumber('+1 213 373 4253') === { country: 'US', phone: '2133734253' }
parseNumber('Phone: +1-213-373-4253.') === { country: 'US', phone: '2133734253' }
parseNumber('+12133734253') === { country: 'US', phone: '2133734253' }

// Parses national numbers provided a default country.
parseNumber('Phone: (213) 373-4253.', 'US') === { country: 'US', phone: '2133734253' }

// Parses phone number extensions.
parseNumber('(213) 373-4253 ext. 123', 'US') === { country: 'US', phone: '2133734253', ext: '123' }

// Parses RFC 3966 phone number URIs.
parseNumber('tel:+78005553535;ext=123') === { country: 'RU', phone: '8005553535', ext: '123' }

If the phone number supplied isn't valid then an empty object {} is returned.

parseNumber('+1 111 111 1111') === {}
parseNumber('(111) 111-1111', 'US') === {}
parseNumber('abcdefg') === {}

#

Available options:

  • defaultCountry : string — Same as the defaultCountry argument.

  • extended : boolean — If set to true then parseNumber() will attempt to parse even a remotely hypothetical phone number even if it is considered "invalid".

<summary>{ extended: true } documentation and examples</summary>

The result of "extended" parsing is an object where

  • country is a country code.
  • phone is a national (significant) number.
  • ext is a phone number extension.
  • countryCallingCode is a country calling code.
  • carrierCodes are only used in Colombia and Brazil and only when dialing within those countries from a mobile phone to a fixed line number.
  • valid: boolean — whether it's a "valid" (real) phone number.
  • possible: boolean — a phone number is considered "possible" when it fits the phone number length rules for a given country. E.g. for US national (significant) number regexp is [2-9]\d{9} and possible national (significant) number length is 10 so a phone number (111) 111-1111 is not a "valid" number because it doesn't match the US national (significant) number regexp but it is a "possible" number because it's 10 digits long.
  • Some or all of these properties may be absent from the result object.

`js // If the number is valid. parseNumber('Phone: (213) 373-4253.', 'US', { extended: true }) === { country: 'US', phone: '2133734253', ext: undefined, countryCallingCode: 1, carrierCode: undefined, valid: true, possible: true }

// If the number is not "valid" but "possible". parseNumber('(111) 111-1111', 'US', { extended: true }) === { country: 'US', phone: '1111111111', ext: undefined, countryCallingCode: 1, carrierCode: undefined, valid: false, possible: true }

// If the number is not "valid" but "possible" // and country can't be derived from it. // (e.g. can't tell if it's a US number or a Canadian number) parseNumber('+1 111 111 1111', { extended: true }) === { country: undefined, phone: '1111111111', ext: undefined, countryCallingCode: 1, carrierCode: undefined, valid: false, possible: true }

// If the number is not "possible" (invalid length). parseNumber('(213) 373', 'US', { extended: true }) === { country: 'US', phone: '213373', ext: undefined, countryCallingCode: 1, carrierCode: undefined, valid: false, possible: false }

// In some cases if the number is extremely not "possible" // then an empty object {} is returned. // // Too short (or too long)

changelog

1.12.22 / 24.9.2025

  • Updated metadata to version 9.0.14:
    • Updated phone metadata for region code(s): CZ, DE, IT, LI, LV, ME, SG, US
    • Updated short number metadata for region code(s): DE
    • New geocoding data for country calling code(s): 1686 (en)
    • Updated geocoding data for country calling code(s): 39 (en, it), 61 (en)
    • Updated carrier data for country calling code(s): 46 (en), 65 (en), 420 (en), 998 (en)
    • Updated / refreshed time zone meta data.

1.12.21 / 23.9.2025

  • Updated metadata to version 9.0.14:
    • Updated phone metadata for region code(s): CZ, DE, IT, LI, LV, ME, SG, US
    • Updated short number metadata for region code(s): DE
    • New geocoding data for country calling code(s): 1686 (en)
    • Updated geocoding data for country calling code(s): 39 (en, it), 61 (en)
    • Updated carrier data for country calling code(s): 46 (en), 65 (en), 420 (en), 998 (en)
    • Updated / refreshed time zone meta data.

1.12.20 / 23.9.2025

  • Updated metadata to version 9.0.14:
    • Updated phone metadata for region code(s): CZ, DE, IT, LI, LV, ME, SG, US
    • Updated short number metadata for region code(s): DE
    • New geocoding data for country calling code(s): 1686 (en)
    • Updated geocoding data for country calling code(s): 39 (en, it), 61 (en)
    • Updated carrier data for country calling code(s): 46 (en), 65 (en), 420 (en), 998 (en)
    • Updated / refreshed time zone meta data.

1.12.19 / 23.9.2025

  • Updated metadata to version 9.0.14:
    • Updated phone metadata for region code(s): CZ, DE, IT, LI, LV, ME, SG, US
    • Updated short number metadata for region code(s): DE
    • New geocoding data for country calling code(s): 1686 (en)
    • Updated geocoding data for country calling code(s): 39 (en, it), 61 (en)
    • Updated carrier data for country calling code(s): 46 (en), 65 (en), 420 (en), 998 (en)
    • Updated / refreshed time zone meta data.

1.12.17 / 12.9.2025

  • (miscellaneous) Updated metadata generator: fixed an error message when a developer attempts to generate custom metadata and the files are not found in Google's github repository.

1.12.16 / 11.9.2025

  • Updated metadata to version 9.0.14:
    • Updated phone metadata for region code(s): CZ, DE, IT, LI, LV, ME, SG, US
    • Updated short number metadata for region code(s): DE
    • New geocoding data for country calling code(s): 1686 (en)
    • Updated geocoding data for country calling code(s): 39 (en, it), 61 (en)
    • Updated carrier data for country calling code(s): 46 (en), 65 (en), 420 (en), 998 (en)
    • Updated / refreshed time zone meta data.

1.12.15 / 28.8.2025

  • Updated metadata to version 9.0.13:
    • Updated phone metadata for region code(s): BT, DE, GY, IL, OM, PA, SG, SR, UY
    • Updated short number metadata for region code(s): UY
    • Updated geocoding data for country calling code(s): 975 (en)
    • Updated carrier data for country calling code(s): 30 (en), 41 (en), 46 (en), 49 (en), 65 (en), 86 (en, zh), 372 (en), 597 (en), 968 (en), 975 (en)

1.12.13 / 20.8.2025

  • Updated metadata to version 9.0.12:
    • Updated phone metadata for region code(s): GB, GG, GM, GY, IM, JE
    • Updated geocoding data for country calling code(s): 61 (en), 81 (en, ja)
    • Updated carrier data for country calling code(s): 220 (en), 370 (en), 592 (en)

1.12.0 / 24.02.2025

1.11.0 / 06.05.2024

  • (TypeScript) Fixed Tagged type to be more strict, as suggested in an issue by Islam Sharabash.

1.10.17 / 08.01.2023

  • Added PhoneNumber.getPossibleCountries() function. It returns a list of countries this phone number could possibly belong to. Can be used when parsing complete international phone numbers containing a "calling code" that is shared between several countries. If parsing such a phone number returns country: undefined then getPossibleCountries() function could be used to somehow speculate about what country could this phone number possibly belong to.

1.10.0 / 18.05.2022

  • Migrated the library to use "ES Modules" export. This shouldn't break anyone's code and it makes it more modern since people asked about this feature.

1.9.48 / 06.02.2022

1.9.45 / xx.01.2022

  • Added AsYouType.getNumberValue() function. The function will be used in react-phone-number-input component. Returns the phone number in E.164 format. For example, for country "US" and input "(222) 333-4444" it will return "+12223334444". Will return undefined if no digits have been input, or when inputting a phone number in national format and no default country or default "country calling code" have been set.

1.9.42 / 05.11.2021

  • Added a better called alias for metadata.full.json — metadata.max.json.

1.9.40 / 02.11.2021

  • Improved format selection in AsYouType formatter: previously it chose the first one before there were at least 3 national (significant) number digits, now it starts filtering out formats right from the start of the national (significant) number.

1.9.36 / 05.10.2021

  • Added a setExt(ext: string) function of a PhoneNumber class instance. It could be useful when formatting phone numbers stored as two separate fields: the phone number itself and the extension part.

1.9.27 / 09.09.2021

  • Added TypeScript "typings" on the exported Metadata class. Also rewrote Metadata class API docs and the description of leading_digits metadata property.

  • TypeScript Metadata exported type was renamed to MetadataJson so that the Metadata class type could be exported as Metadata.

1.9.26 / 05.09.2021

  • Added validatePhoneNumberLength() function: same as isPossiblePhoneNumber() but tells the actual reason why a phone number is not possible: TOO_SHORT, TOO_LONG, INVALID_LENGTH, etc.
validatePhoneNumberLength('abcde') === 'NOT_A_NUMBER'
validatePhoneNumberLength('444 1 44') === 'INVALID_COUNTRY'
validatePhoneNumberLength('444 1 44', 'TR') === 'TOO_SHORT'
validatePhoneNumberLength('444 1 444', 'TR') === undefined
validatePhoneNumberLength('444 1 4444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 44444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 444444', 'TR') === undefined
validatePhoneNumberLength('444 1 4444444444', 'TR') === 'TOO_LONG'

1.9.20 / 07.06.2021

  • Changed formatting numbers in IDD format to always use the preferred IDD prefix (if defined), not just in cases when a country has multiple IDD prefixes. This means that it will output 8~10 as the prefix instead of 810 for some regions (like Uzbekistan) that have this tilde in their IDD prefix (the tilde designates that the user should wait before continuing to dial).

1.9.11 / 10.02.2021

  • Added extract: false option on parsePhoneNumberFromString(): it enables a bit "stricter" parsing in a way that it attempts to parse the entire text as a phone number rather than extracting a phone number from text. For example, with extract: false option, "(213) 373-4253" is parsed as a valid phone number, but "Call: (213) 373-4253" is not, because the "Call: " part doesn't automatically get trimmed in this case. If there's version 2.x, I guess extract: false will be the default behavior because it looks more appropriate than the default "extract" behavior of Google's libphonenumber.

  • Added isPossiblePhoneNumber() and isValidPhoneNumber() functions, which are basically shortucts to parsePhoneNumberFromString(text, { extract: false }) and then .isValid()/.isPossible().

1.9.5 / 01.12.2020

  • Fixed the issue with findPhoneNumbersInText() returning incorrect startAt and endsAt positions in some cases.

1.9.4 / 13.11.2020

  • Refactored the main ES6 export in order to support "tree shaking".

1.9.3 / 11.11.2020

  • Added AsYouType.getChars() method.

  • Added formatting of international phone numbers that have been input without a leading +.

1.9.2 / 08.11.2020

  • Metadata version is now an integer instead of a semver version. Semver versions of previously generated metadata are automatically converted into an integer version.

1.9.1 / 08.11.2020

  • Merged the latest Google's patch on parsing phone number extensions.

1.9.0 / 08.11.2020

  • Refactored AsYouType formatter.

  • (could be a breaking change for some) Some people might have used some of the undocumented AsYouType instance properties like .countryCallingCode, .nationalNumber, etc: those have been moved to a new .state object. The .state object is also not part of the public API, so developers shouldn't use it: use the documented getter methods instead. The .country property of AsYouType instance still stays: not because it hasn't been moved (it has been and is emulated), but because it has been part of an official (now legacy) API of AsYouType formatter.

  • (misc) Renamed asYouType instance method getCountryCallingCode() to getCountryCode(). The older name still works.

  • (could be a build-time breaking change for custom metadata) For those who were generating custom metadata, the libphonenumber-generate-metadata console command has been moved to a separate package called libphonenumber-metadata-generator. The applications that're using it should do npm install libphonenumber-metadata-generator --save-dev and then use the new libphonenumber-metadata-generator command instead of the old one (only the name changed). See instructions.

1.8.6 / 05.11.2020

  • Refactored AsYouType formatter.

  • Fixed AsYouType formatter not formatting numbers in some cases like, for example, certain types of Argentinian mobile numbers.

  • humanReadable option of "IDD" formatting has been removed: now it's always true. The rationale is that Google's formatOutOfCountryCallingNumber() original function always formats in "human readable" format.

1.8.3 / 03.10.2020

  • (advanced) Fixed metadata.mobile.json and generating "custom" metadata: now it won't include non-relevant phone number types. Previously, metadata.mobile.json (and any other "custom"-generated metadata) included all phone number types for cases when there're several countries corresponding to the same country calling code (for example, US and CA). So, in case of metadata.mobile.json, for DE it only contained mobile phone number type, but for US and CA it contained all phone number types (this has been unnoticed until this release). Now it only contains mobile phone number types for any country, as it's supposed to be. This change didn't result in any significant "mobile" metadata size reduction: just 105 KB -> 95 KB.

1.8.1 / 23.09.2020

  • Renamed parsePhoneNumber() named export to parsePhoneNumberWithError(). The older name still works.

1.8.0 / 22.09.2020

  • Promoted parsePhoneNumberFromString() named export to a default export due to the name being too verbose.

1.7.50 / 05.04.2020

  • Added some utility functions to AsYouType:
/**
 * Returns `true` if the phone number is being input in international format.
 * In other words, returns `true` if and only if the parsed phone number starts with a `"+"`.
 * @return {boolean}
 */
isInternational()

/**
 * Returns the "country calling code" part of the phone number.
 * Returns `undefined` if the number is not being input in international format.
 * Returns "country calling code" for "non-geographic" phone numbering plans too.
 * @return {string} [countryCallingCode]
 */
getCountryCallingCode()

/**
 * Returns a two-letter country code of the phone number.
 * Returns `undefined` for "non-geographic" phone numbering plans.
 * Returns `undefined` if no phone number has been input yet.
 * @return {string} [country]
 */
getCountry()

/**
 * Returns `true` if the phone number is "possible".
 * Is just a shortcut for `PhoneNumber.isPossible()`.
 * @return {boolean}
 */
isPossible()

/**
 * Returns `true` if the phone number is "valid".
 * Is just a shortcut for `PhoneNumber.isValid()`.
 * @return {boolean}
 */
isValid()

1.7.38 / 04.02.2020

  • Removed the "001" country code ("Non-Geographic Entity"): now in case of "non-geographic" phone numbers their country is just undefined. Instead, PhoneNumber class has an .isNonGeographic() method.

  • Fixed "non-geographic" numbers .isPossible() === false bug.

1.7.35 / 03.02.2020

  • Fixed "Non-Geographic Entities" (001 country code).

1.7.32 / 03.02.2020

  • Refactored the code. Mostly AsYouType formatter. AsYouType.input() no longer accepts "falsy" values like null: instead, it only accepts strings.

  • Fixed AsYouType formatter bugs (#318).

  • Added nationalPrefix: boolean option to PhoneNumber.format() — Some phone numbers can be formatted both with national prefix and without it. In such cases the library defaults to "with national prefix" (for legacy reasons). Pass nationalPrefix: false option to force formatting without national prefix in such cases.

  • Renamed findNumbers(text, { v2: true }) to findPhoneNumbersInText(text), and searchNumbers(text, { v2: true }) to searchPhoneNumbersInText(text).

1.7.27 / 18.11.2019

  • Added getCountries() function that returns a list of all available two-letter country codes. This is to prevent some users from having to deal with Unknown country error.

1.7.6 / 11.01.2019

  • findNumbers(), searchNumbers(), PhoneNumberMatcher don't throw "Unknown country" error anymore: a non-existent country is simply ignored instead. Same goes for getExampleNumber() and getExtPrefix().

  • parsePhoneNumberFromString() doesn't return undefined if a non-existent default country is passed: it simply ignores such country instead and still parses international numbers.

  • Added isSupportedCountry(country) function.

  • Added CDN bundles for min/max/mobile sub-packages.

  • Moved demo to max metadata (was min previously).

  • Added TypeScript definitions for min/max/mobile/core sub-packages.

1.7.1 / 01.12.2018

  • Added /min, /max, /mobile and /custom subpackages pre-wired with different flavors of metadata. See the relevant readme section for more info.

  • Added parsePhoneNumberFromString() function (which doesn't throw but instead returns undefined).

1.7.0 / 31.12.2018

  • Refactored the code to remove cyclic dependencies which caused warnings on React Native. It's not a breaking change but it's still a big code diff overall so incremented the "minor" version number.

1.6.2 / 18.10.2018

  • Support Russian extension character "доб" as a valid one while parsing the numbers.

1.6.1 / 18.10.2018

  • Added .getNumber() method to AsYouType formatter instance. Returns a PhoneNumber.

1.6.0 / 17.10.2018

  • Added parsePhoneNumber() function and PhoneNumber class.

  • Added v2: true option to findNumbers() function.

  • Added getExampleNumber() function.

  • Added isPossibleNumber() function.

  • In formatNumber() renamed National to NATIONAL and International to INTERNATIONAL. The older variants still work but are considered deprecated.

  • (metadata file internal format breaking change) (doesn't affect users of this library) If anyone was using metadata files from this library bypassing the library functions (i.e. those who parsed metadata.min.json file manually) then there's a new internal optimization introduced in this version: previously formats were copy-pasted for each country of the same region (e.g. NANPA) while now the formats are only defined on the "main" country for region and other countries simply read the formats from it at runtime. This reduced the default metadata file size by 5 kilobytes.

1.5.0 / 26.09.2018

  • Deprecated findPhoneNumbers(), searchPhoneNumbers() and PhoneNumberSearch. Use findNumbers(), searchNumbers() and PhoneNumberMatcher instead. The now-deprecated functions were a half-self-made implementation of Google's Java findNumbers() until the Java code was ported into javascript and passed tests. The port of Google's Java implementation is supposed to find numbers more correctly. It hasn't been tested by users in production yet, but the same tests as for the previous implementation of findPhoneNumbers() pass, so seems that it can be used in production.

1.4.6 / 12.09.2018

  • Fixed formatNumber('NATIONAL') not formatting national phone numbers with a national prefix when it's marked as optional (e.g. Russia). Before it didn't add national prefix when formatting national numbers if national prefix was marked as optional. Now it always adds national prefix when formatting national numbers even when national prefix is marked as optional.

1.4.5 / 07.09.2018

  • A bug in matches_entirely was found by a user which resulted in incorrect regexp matching in some cases, e.g. when there was a | in a regexp. This could cause incorrect parseNumber() results, or any other weird behaviour.

1.4.0 / 03.08.2018

  • Changed the output of AsYouType formatter. E.g. before for US and input 21 it was outputting (21 ) which is not good for phone number input (not intuitive and is confusing). Now it will not add closing braces which haven't been reached yet by the input cursor and it will also strip the corresponding opening braces, so for US and input 21 it now is just 21, and for 213 it is (213).

  • (could be a breaking change for those who somehow used .template property of an AsYouType instance) Due to the change in AsYouType formatting the .template property no longer strictly corresponds to the output, e.g. for US and input 21 the output is now 21 but the .template is still (xxx) xxx-xxxx like it used to be in the older versions when the output was (21 ). Therefore, a new function has been added to AsYouType instance called .getTemplate() which will return the partial template for the currently input value, so for input 21 the output will be 21 and .getTemplate() will return xx, and for input 213 the output will be (213) and .getTemplate() will return (xxx). So there is this difference between the new .getTemplate() function and the old .template property: the old .template property always returns the template for a fully entered phone number and the new .getTemplate() function always returns the template for the partially entered phone number, i.e. for the partially entered number (213) 45 it will return template (xxx) xx so it's a one-to-one correspondence now.

1.3.0 / 25.07.2018

  • Fixed parseNumber(), isValidNumber() and getNumberType() in some rare cases (made them a bit less strict where it fits): previously they were treating defaultCountry argument as "the country" in case of local numbers, e.g. isValidNumber('07624 369230', 'GB') would be false because 07624 369230 number belongs to IM (the Isle of Man). While IM is not GB it should still be true because GB is the default country, without it necessarily being the country.

  • Added a new function isValidNumberForRegion(number, country) which mimics Google's libphonenumber's one.

1.2.13 / 30.05.2018

  • Fixed a previously unnoticed bug regarding parsing RFC3966 phone URIs: previously : was mistakenly being considered a key-value separator instead of =. E.g. it was parsing RFC3966 phone numbers as tel:+78005553535;ext:123 instead of tel:+78005553535;ext=123. The bug was found and reported by @cdunn.

1.2.6 / 12.05.2018

  • Removed parseNumber()'s fromCountry parameter used for parsing IDD prefixes: now it uses defaultCountry instead. formatNumber()'s fromCountry parameter stays and is not removed.

1.2.5 / 11.05.2018

  • Optimized metadata a bit: using 0 instead of null/false and 1 instead of true.

1.2.0 / 08.05.2018

  • Added support for IDD prefixes — parse() now parses IDD-prefixed phones if fromCountry option is passed, format() now has an IDD format.

1.1.7 / 01.04.2018

  • Added parseNumber() and formatNumber() aliases for parse() and format(). Now these are the default ones, and parse() and format() names are considered deprecated. The rationale is that parse() and format() function names are too unspecific and can clash with other functions declared in a javascript file. And also searching in a project for parseNumber and formatNumber is easier than searching in a project for parse and format.

  • Fixed parseRFC3966() and formatRFC3966() non-custom exports.

1.1.4 / 15.03.2018

  • parse() is now more forgiving when parsing invalid international numbers. E.g. parse('+49(0)15123020522', 'DE') doesn't return {} and instead removes the invalid (0) national prefix from the number.

1.1.1 / 10.03.2018

  • Added PhoneNumberSearch class for asynchronous phone number search.

1.1.0 / 09.03.2018

  • Added findPhoneNumbers function.

1.0.22 / 13.02.2018

  • Added parseRFC3966 and formatRFC3966 functions which are exported.

1.0.18 / 12.02.2018

  • Fixed custom metadata backwards compatibility bug introduced in 1.0.16. All people who previously installed 1.0.16 or 1.0.17 should update.
  • Refactored metadata module which now supports versioning by adding the version property to metadata JSON.

1.0.17 / 07.02.2018

  • Fixed RFC3966 format not prepending tel: to the output.
  • Renamed { possible: true } option to { extended: true } and the result is now more verbose (see the README).
  • Added possible_lengths property in metadata: metadata generated using previous versions of the library should be re-generated with then new version.

1.0.16 / 07.02.2018

  • (experimental) Added { possible: true } option for parse() for parsing "possible numbers" which are not considered valid (like Google's demo does). E.g. parse('+71111111111', { possible: true }) === { countryCallingCode: '7', phone: '1111111111', possible: true } and format({ countryCallingCode: '7', phone: '1111111111' }, 'E.164') === '+71111111111'.
  • getPhoneCode name is deprecated, use getCountryCallingCode instead.
  • getPhoneCodeCustom name is deprecated, use getCountryCallingCodeCustom instead.
  • AsYouType.country_phone_code renamed to AsYouType.countryCallingCode (but no one should have used that property).

1.0.0 / 21.01.2018

  • If country: string argument is passed to parse() now it becomes "the default country" rather than "restrict to country" ("restrict to country" option is gone).
  • parse() options argument changed: it's now an undocumented feature and can have only a single option inside — defaultCountry: string — which should be passed as a string argument instead.
  • Removed all previously deprecated stuff: all underscored exports (is_valid_number, get_number_type and as_you_type), lowercase exports for asYouType and asYouTypeCustom (use AsYouType and AsYouTypeCustom instead), "International_plaintext" format (use "E.164" instead).
  • Integer phone numbers no longer get automatically converted to strings.
  • parse(), isValidNumber(), getNumberType() and format() no longer accept undefined phone number argument: it must be either a string or a parsed number object having a string phone property.

0.4.52 / 21.01.2018

  • Added formatExtension(number, extension) option to format()

0.4.50 / 20.01.2018

  • Added support for phone number extensions.
  • asYouType name is deprecated, use AsYouType instead (same goes for asYouTypeCustom).
  • is_valid_number, get_number_type and as_you_type names are deprecated, use camelCased names instead.
  • International_plaintext format is deprecated, use E.164 instead.
  • Added RFC3966 format for phone number URIs (tel:+1213334455;ext=123).

0.4.2 / 30.03.2017

  • Added missing getNumberTypeCustom es6 export

0.4.0 / 29.03.2017

  • Removed .valid from "as you type" formatter because it wasn't reliable (gave false negatives). Use isValidNumber(value) for phone number validation instead.

0.3.11 / 07.03.2017

  • Fixed a bug when "as you type" formatter incorrectly formatted the input using non-matching phone number formats

0.3.8 / 25.02.2017

  • Loosened national prefix requirement when parsing (fixed certain Brazilian phone numbers parsing)

0.3.6 / 16.02.2017

  • Added more strict validation to isValidNumber
  • Fixed CommonJS export for getNumberType

0.3.5 / 15.02.2017

  • Now exporting getNumberType function

0.3.0 / 29.01.2017

  • Removed libphonenumber-js/custom.es6 exported file: now everything should be imported from the root package in ES6-capable bundlers (because tree-shaking actually works that way)
  • Now custom functions like parse, format and isValidNumber are not bound to custom metadata: it's passed as the last argument instead. And custom asYouType is now not a function — instead, asYouType constructor takes an additional metadata argument

0.2.29 / 12.01.2017

  • Fixed update-metadata utility

0.2.26 / 02.01.2017

  • Added national prefix check for parse and isPhoneValid

0.2.25 / 30.12.2016

  • A bit more precise valid flag for "as you type" formatter

0.2.22 / 28.12.2016

  • Added metadata update bin command for end users (see README)
  • Added the ability to include extra regular expressions for finer-grained phone number validation

0.2.20 / 28.12.2016

  • Added the ability to use custom-countries generated metadata as a parameter for the functions exported from this library

0.2.19 / 25.12.2016

  • Small fix for "as you type" to not prepend national prefix to the number being typed

0.2.13 / 23.12.2016

  • Reset default_country for "as you type" if the input is an international phone number

0.2.12 / 23.12.2016

  • (misc) Small fix for format() when the national number is undefined

0.2.10 / 23.12.2016

  • Better "as you type" matching: when the national prefix is optional it now tries both variants — with the national prefix extracted and without

0.2.9 / 22.12.2016

  • Exporting metadata and getPhoneCode()

0.2.6 / 22.12.2016

  • Fixed a minor bug in "as you type" when a local phone number without national prefix got formatted with the national prefix

0.2.2 / 14.12.2016

  • Fixed a bug when country couldn't be parsed from a phone number in most cases

0.2.1 / 10.12.2016

  • Added .country_phone_code readable property to "as you type" formatter

0.2.0 / 02.12.2016

  • "As you type" formatter's country_code argument is now default_country_code, and it doesn't restrict to the specified country anymore.

0.1.17 / 01.12.2016

  • "As you type" formatter template fix for national prefixes (which weren't replaced with x-es)

0.1.16 / 01.12.2016

  • "As you type" formatter now formats the whole input passed to the .input() function one at a time without splitting it into individual characters (which yields better performance)

0.1.14 / 01.12.2016

  • Added valid, country and template fields to "as you type" instance

0.1.12 / 30.11.2016

  • Managed to reduce metadata size by another 5 KiloBytes removing redundant (duplicate) phone number type regular expressions (because there's no "get phone type" API in this library).

0.1.11 / 30.11.2016

  • Managed to reduce metadata size by 10 KiloBytes removing phone number type regular expressions when leading_digits are present.

0.1.10 / 30.11.2016

  • Turned out those numerous bulky regular expressions (<fixedLine/>, <mobile/>, etc) are actually required to reliably infer country from country calling code and national phone number in cases where there are multiple countries assigned to the same country phone code (e.g. NANPA), so I've included those big regular expressions for those ambiguous cases which increased metadata size by 20 KiloBytes resulting in a total of 90 KiloBytes for the metadata.

0.1.9 / 30.11.2016

  • Small fix for "as you type" formatter: replacing digit placeholders (punctuation spaces) with regular spaces in the output

0.1.8 / 29.11.2016

  • Fixed a bug when national prefix 1 was present in "as you type" formatter for NANPA countries (while it shouldn't have been present)

0.1.7 / 29.11.2016

  • (may be a breaking change) renamed .clear() to .reset() for "as you type" formatter

0.1.5 / 29.11.2016

  • Better asYouType (better than Google's original "as you type" formatter)

0.1.0 / 28.11.2016

  • Added asYouType and isValidNumber.

0.0.3 / 24.11.2016

  • Added format function.

0.0.1 / 24.11.2016

  • Initial release. parse function is working.