# libphonenumber-js [![npm version](https://img.shields.io/npm/v/libphonenumber-js.svg?style=flat-square)](https://www.npmjs.com/package/libphonenumber-js) [![npm downloads](https://img.shields.io/npm/dm/libphonenumber-js.svg?style=flat-square)](https://www.npmjs.com/package/libphonenumber-js) [![coverage](https://img.shields.io/coveralls/catamphetamine/libphonenumber-js/master.svg?style=flat-square)](https://coveralls.io/r/catamphetamine/libphonenumber-js?branch=master) A simpler and smaller rewrite of Google Android's [`libphonenumber`](https://github.com/google/libphonenumber/) library in javascript/typescript. Parse and format personal phone numbers. [See Demo](https://catamphetamine.gitlab.io/libphonenumber-js/) If you’re trying to build a React component with it, take a look at [`react-phone-number-input`](https://www.npmjs.com/package/react-phone-number-input). ## libphonenumber Google's [`libphonenumber`](https://github.com/googlei18n/libphonenumber) is an ultimate phone number formatting and parsing library developed by Google for [Android](https://en.wikipedia.org/wiki/Android_(operating_system)) phones. It is written in C++ and Java, and, while it has an [official autogenerated javascript port](https://github.com/googlei18n/libphonenumber/tree/master/javascript), that port is tightly coupled to Google's `closure` javascript framework, and when compiled into a [bundle](https://github.com/ruimarinho/google-libphonenumber), the total weight becomes about 550 kB (350 kB code + 200 kB metadata). `libphonenumber-js` works around the bundle size issue by stripping down both code and metadata: the code was rewritten in javascript/typescript from scratch, and a developer can now choose which parts of metadata to include.
Here's a full comparison to Google's libphonenumber for those who're interested. ###### * 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). * Comes with TypeScript definitions. * 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"](https://www.tatango.com/blog/sms-short-codes-what-every-business-needs-to-know/) — 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](https://github.com/catamphetamine/libphonenumber-js/issues/400) numbers, which are a "catchy" "short" form of regular "landline" numbers and are mainly used in [advertisement](https://www.youtube.com/watch?v=Y0HchzE-7rM). * 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"](#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"](https://www.bandwidth.com/glossary/carrier-identification-code-cic/) 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](https://issuetracker.google.com/issues/335892662) when Canadian numbers `+1310xxxx` wheren't considered possible.
## Install ```sh npm install libphonenumber-js --save ``` Alternatively, one could include it on a web page [directly](#cdn) via a ` ``` where `[version]` is an npm package version range (for example, `1.x` or `^1.7.6`) and `[type]` is the bundle type: `min`, `max` or `mobile`. ## Metadata Metadata is generated from Google's [`PhoneNumberMetadata.xml`](https://github.com/googlei18n/libphonenumber/blob/master/resources/PhoneNumberMetadata.xml) by transforming XML into JSON and removing unnecessary fields. See [metadata fields description](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md). ### Programmatic access Metadata can be accessed programmatically by using the exported `Metadata` class. First, create a `Metadata` class instance: ```js import { Metadata } from 'libphonenumber-js' const metadata = new Metadata() ``` Then, select a ["numbering plan"](https://en.wikipedia.org/wiki/Telephone_numbering_plan) (a country): ```js metadata.selectNumberingPlan('US') ``` After that, the following methods of `metadata.numberingPlan` can be called: * `leadingDigits(): string?` — Returns ["leading digits"](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md#leading_digits) pattern. * `possibleLengths(): number[]` — Returns a list of [possible lengths](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md#possible_lengths) of a national (significant) number. * `IDDPrefix(): string` — Returns an [International Direct Dialing](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md#idd_prefix) prefix. * `defaultIDDPrefix(): string?` — Returns a [default International Direct Dialing](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md#default_idd_prefix) prefix when there're multiple ones available. Example: ```js import { Metadata } from 'libphonenumber-js' const metadata = new Metadata() metadata.selectNumberingPlan('US') metadata.numberingPlan.leadingDigits() === undefined metadata.numberingPlan.possibleLengths() === [10] metadata.numberingPlan.IDDPrefix() === '011' metadata.numberingPlan.defaultIDDPrefix() === undefined ``` Example with metadata argument: ```js import { Metadata } from 'libphonenumber-js/core' import min from 'libphonenumber-js/min/metadata' // import max from 'libphonenumber-js/max/metadata' // import mobile from 'libphonenumber-js/mobile/metadata' const metadata = new Metadata(min) ``` As one can see, the [`Metadata` class](https://gitlab.com/catamphetamine/libphonenumber-js/-/blob/master/source/metadata.js) is not documented much. Partially, that's because its usage is not necessarily encouraged, but it's still used, for example, in [`react-phone-number-input`](https://gitlab.com/catamphetamine/react-phone-number-input/-/blob/master/source/helpers/phoneInputHelpers.js) to get the "leading digits" for a country, or to get the maximum phone number length for a country. Stick to the methods documented above and don't call any other methods. If you think there's a need to call any other methods not mentioned above, create an issue with a discussion. ### Custom metadata This library comes prepackaged with [three types of metadata](#min-vs-max-vs-mobile-vs-core). Sometimes, if only a specific set of countries is needed in a project, and a developer really wants to reduce the resulting bundle size, say, by 50 kilobytes, then they could create a "custom" slice of metadata using [`libphonenumber-metadata-generator`](npmjs.com/libphonenumber-metadata-generator) and then pass it as the last argument to the functions imported from the `/core` subpackage. Note that if you'll be using your own "custom" metadata then you're responsible for keeping it up-to-date because Google regularly updates their metadata. ```js import parsePhoneNumber, { AsYouType } from 'libphonenumber-js/core' import metadata from './metadata.RU.json' const phoneNumber = parsePhoneNumber(' 8 (800) 555-35-35 ', 'RU', metadata) if (phoneNumber) { phoneNumber.country === 'RU' phoneNumber.number === '+78005553535' } new AsYouType('RU', metadata).input('88005553535') === '8 (800) 555-35-35' ``` ## Maintenance This library reuses Google's metadata. Google periodically publishes a new version of the metadata, with the changes described in their [release notes](https://github.com/googlei18n/libphonenumber/blob/master/release_notes.txt). Those're usually minor fixes whenever some country decides to adjust their telephone numbering plan. After Google updates their metadata, this library pulls the updated metadata from Google's repository and publishes a new version of itself on `npm`. The metadata pulling process is automated by running `metadata:update:job` npm script. The script detects changes to `PhoneNumberMetadata.xml` file in Google `libphonenumber`'s repo and, if there are any changes, it pulls the latest metadata, transforms it, pushes the changes to the repository, builds a new version of the package and publishes it on `npm` using "trusted publishing". The script is run daily via GitLab CI (could be GitHub CI if they weren't [unreliable](#gitHub-repository-status)). Also Google sometimes (extremely rarely) updates their code: * [`phonenumberutil.js`](https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js) — is mirrored as functions: `parseNumber()`, `formatNumber()`, `isValidNumber()`, `getNumberType()` * [`AsYouTypeFormatter.java`](https://github.com/google/libphonenumber/blob/master/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java) — is mirrored as `AsYouType` class * [`PhoneNumberMatcher.java`](https://github.com/googlei18n/libphonenumber/blob/master/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java) — is mirrored as `findPhoneNumbersInText()` function The latest sync-up with Google's code was on May 25th, 2026. ## Contributing After cloning this repo, install the dependencies: ```sh npm install ``` This library is written in ES6 and uses [Babel](http://babeljs.io/) for ES5 transpilation during the "build" step: ```sh npm run build ``` After making any code changes, run the tests: ```sh npm test ``` After the tests pass, check the code coverage ("statements" percentage) — it should remain at 100%: ```sh npm run test-coverage ``` A detailed code coverage report can be viewed by opening `./coverage/lcov-report/index.html` file. Sidenote: Because code coverage is tested using `istanbul` with `babel`, it may very rarely introduce "quirky" situtations when `babel` polyfill code gets mistakenly included in the analysis report, resulting in a "mysterious" decrease of the code coverage. The workaround is to re-implement those polyfills in a simpler manner or to use `/* istanbul ignore file */` directive. To test the updated code on a real project before publishing a new release, one could use "pack-and-install" trick to simulate publishing a new release. ```sh npm pack ``` It will `build`, `test` and then create a `.tgz` archive that can be installed from a project folder just like a normal `npm` package. ```sh npm install [module name with version].tar.gz ``` ## Advertisement If you like this library then you might also like: * [`react-phone-number-input`](https://npmjs.com/package/react-phone-number-input) — A `React` component for phone number input. * [`javascript-time-ago`](https://npmjs.com/package/javascript-time-ago) — An international human-readable past or future date formatter. Example: `"2 days ago"`. * [`react-time-ago`](https://npmjs.com/package/react-time-ago) — A `React` component for international human-readable past or future date formatter. Example: `"2 days ago"`. * [`read-excel-file`](https://www.npmjs.com/package/read-excel-file) — A simple and easy-to-use `*.xlsx` file reader (client-side or server-side). * [`write-excel-file`](https://www.npmjs.com/package/write-excel-file) — A simple and easy-to-use `*.xlsx` file writer (client-side or server-side). * [`flexible-json-schema`](https://www.npmjs.com/package/flexible-json-schema) — A simple and easy-to-use `*.json` schema data validator / parser. * [`navigation-stack`](https://www.npmjs.com/package/navigation-stack) — Navigation in a Single-Page Application. * [`virtual-scroller`](https://www.npmjs.com/package/virtual-scroller) — A universal implementation of a "virtual scroller" infinite list scrolling component: only renders the rows that fit the screen bounds. ## License Google's `libphonenumber` is [licensed](https://github.com/google/libphonenumber/blob/master/LICENSE) under Apache 2. [Apache 2](https://en.wikipedia.org/wiki/Apache_License#Licensing_conditions) does not require a derivative work of the software, or modifications to the original, to be distributed using the same license. Hence, this library is licensed under [MIT](LICENSE), which is [compatible](https://www.quora.com/Is-the-MIT-license-compatible-with-the-Apache-License-Version-2-APLv2) with Apache 2. The Apache license is terminated if the user sues anyone over patent infringement related to the software covered by the license. This condition is added in order to prevent patent litigations.