Package Exports
- libphonenumber-js
- libphonenumber-js/bundle/libphonenumber-js.min
- libphonenumber-js/index.common.js
- libphonenumber-js/metadata.min
- libphonenumber-js/metadata.min.json
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (libphonenumber-js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
libphonenumber-js
[![NPM Version][npm-badge]][npm] [![Build Status][travis-badge]][travis] [![Test Coverage][coveralls-badge]][coveralls]
A simpler (and smaller) rewrite of Google Android's famous libphonenumber library: easy phone number parsing and formatting in javascript.
LibPhoneNumber
libphonenumber is a phone number formatting and parsing library released by Google, originally developed for (and currently used in) Google's Android mobile phone operating system. Implementing a rigorous phone number formatting and parsing library was crucial for the phone OS overall usability (back then, in the early 2000s, it was originally meant to be a phone after all, not just a SnapChat device).
libphonenumber-js is a simplified pure javascript port of the original libphonenumber library (written in C++ and Java because those are the programming languages used in Android OS). While libphonenumber has an official javascript port which is being maintained by Google, it is tightly coupled to Google's closure javascript utility framework. It still can be compiled into one big bundle which weighs 220 KiloBytes — quite a size for a phone number input component. It can be reduced to a specific set of countries only but that wouldn't be an option for a worldwide international solution.
One part of me was curious about how all this phone matching machinery worked, and another part of me was curious if there's a way to reduce those 220 KiloBytes to something more reasonable while also getting rid of the closure library and rewriting it all in pure javascript. So, that was my little hackathon for a couple of weeks, and seems that it succeeded. The resulting library does everything a modern web application needs while maintaining a much smaller size of about 75 KiloBytes.
Difference from Google's libphonenumber
- Pure javascript, doesn't require any 3rd party libraries
- Metadata size is just about 75 KiloBytes while the original
libphonenumbermetadata size is about 200 KiloBytes - Better "as you type" formatting (and also more iPhone-alike style)
- Doesn't parse alphabetic phone numbers like
1-800-GOT-MILKas we don't use telephone sets in the XXIst century that much (and we have phonebooks in your mobile phones) - Doesn't handle carrier codes: they're only used in Colombia and Brazil, and only when dialing within those countries from a mobile phone to a fixed line number (the locals surely already know those carrier codes by themselves)
- Assumes all phone numbers being
formatted are internationally diallable, because that's the only type of phone numbers users are supposed to be inputting on websites (no one inputs short codes, emergency telephone numbers like911, etc.) - Doesn't parse phone numbers with extensions (again, this is not the type of phone numbers users should input on websites — they're supposed to input their personal mobile phone numbers, or home stationary phone numbers if they're living in an area where celltowers don't have a good signal, not their business/enterprise stationary phone numbers)
- Doesn't use
possibleDigitsdata to speed up phone number pre-validation (it just skips to the regular expression check itself) - Doesn't distinguish between fixed line, mobile, pager, voicemail, toll free and other XXth century bullsh*t
- Doesn't format phone numbers for "out of country dialing", e.g.
011 ...in the US (again, just use the+...notation accepted worldwide for mobile phones) - Doesn't parse
tel:...URIs (RFC 3966) because it's not relevant for user-facing web experience - When formatting international numbers replaces all braces, dashes, etc with spaces (because that's the logical thing to do, and leaving braces in an international number isn't)
Installation
npm install libphonenumber-js --saveUsage
import { parse, format, asYouType } from 'libphonenumber-js'
parse('8 (800) 555 35 35', 'RU')
// { country: 'RU', phone: '8005553535' }
format('2133734253', 'US', 'International')
// '+1-213-373-4253'
new asYouType().input('+12133734')
// '+1 213 373 4'
new asYouType('US').input('2133734')
// '(213) 373-4'Country code definition
"Country code" means either a two-letter ISO country code (like US) or a special 001 country code used for non-geographical entities (as per Google's libphonenumber library). For example, +7 800 555 35 35 phone number belongs to Russia so it has RU country code where as +800 1 1111 1111 phone number could belong to any country so it has 001 country code.
API
parse(text, options)
options can be either an object
country:
{
restrict — (country code)
the phone number must be in this country
default — (country code)
default country to use for phone number parsing and validation
(if no country code could be derived from the phone number)
}or just a country code which is gonna be country.restrict.
Returns { country, phone } where country is a country code, and phone is a national (significant) number. If the phone number supplied isn't valid then an empty object {} is returned.
parse('+1-213-373-4253') === { country: 'US', phone: '2133734253' }
parse('(213) 373-4253', 'US') === { country: 'US', phone: '2133734253' }format(parsed_number, format)
Formats a phone number using one of the following formats:
International— e.g.+1 213 373 4253International_plaintext— (akaE.164) e.g.+12133734253National— e.g.(213) 373-4253
parsed_number argument should be taken from the result of the parse() function call: { country, phone }. phone must be a national (significant) number (i.e. no national prefix). parsed_number argument can also be expanded into two arguments:
format({ country: 'US', phone: '2133734253' }, 'International') === '+1 213 373 4253'
format('2133734253', 'US', 'International') === '+1 213 373 4253'isValidNumber(number, country_code)
(aka is_valid_number)
This function is simply a wrapper for parse: if parse returns an empty object then the phone number is not valid.
isValidNumber('+1-213-373-4253') === true
isValidNumber('+1-213-373') === false
isValidNumber('(213) 373-4253', 'US') === true
isValidNumber('(213) 37', 'US') === falseclass asYouType(default_country_code)
(aka as_you_type)
Creates a formatter for partially entered phone number. The two-letter default_country_code is optional and, if specified, is gonna be the default country for the phone number being input (in case it's not an international one). The instance of this class has two methods:
input(text)— takes any text and appends it to the input; returns the formatted phone numberreset()— resets the input
The instance of this class has also these fields:
valid— is the phone number being input a valid one alreadycountry— a country code of the country this phone belongs tocountry_phone_code— a phone code of thecountrynational_number— national number part (so far)template— currently used phone number formatting template, where digits (and the plus sign, if present) are denoted byx-es
new asYouType().input('+12133734') === '+1 213 373 4'
new asYouType('US').input('2133734') === '(213) 373-4'
const formatter = new asYouType()
formatter.input('+1-213-373-4253') === '+1 213 373 4253'
formatter.valid === true
formatter.country === 'US'
formatter.country_phone_code = '1'
formatter.template === 'xx xxx xxx xxxx'Metadata generation
Metadata is generated from Google's original PhoneNumberMetadata.xml by transforming XML into JSON and removing unnecessary fields.
How to update metadata:
- Fork this repo
npm installnpm run metadata:update- Submit a pull request
To update metadata first it downloads the new PhoneNumberMetadata.xml into the project folder replacing the old one. Then it generates JSON metadata out of the XML one. After that it runs the tests and commits the new metadata.
Bug reporting
If you spot any inconsistencies with the original Google's libphonenumber then create an issue in this repo.
Webpack
If you're using Webpack (which you most likely are) then make sure that
- You have
json-loaderset up for*.jsonfiles in Webpack configuration json-loaderdoesn'texclude/node_modules/- If you override
resolve.extensionsin Webpack configuration then make sure.jsonextension is present in the list
Standalone
For those who aren't using bundlers for some reason there's a way to build a standalone version of the library
git clone https://github.com/halt-hammerzeit/libphonenumber-js.gitnpm installnpm run browser-build- See the
bundlefolder forlibphonenumber-js.min.js
<script src="/scripts/libphonenumber-js.min.js"></script>
<script>
var libphonenumber = window['libphonenumber-js']
alert(new libphonenumber.asYouType('US').input('213-373-4253'))
</script>Including only a specific set of countries
The following command will generate metadata only for the specified set of countries (if anyone needs that)
npm run metadata:generate NL,BE,FR,DE,LU,AT
# The resulting `metadata.min.json` will only contain those countriesContributing
After cloning this repo, ensure dependencies are installed by running:
npm installThis module is written in ES6 and uses Babel for ES5 transpilation. Widely consumable JavaScript can be produced by running:
npm run buildOnce npm run build has run, you may import or require() directly from
node.
After developing, the full test suite can be evaluated by running:
npm testWhen you're ready to test your new functionality on a real project, you can run
npm packIt will build, test and then create a .tgz archive which you can then install in your project folder
npm install [module name with version].tar.gzLicense
MIT [npm]: https://www.npmjs.org/package/libphonenumber-js [npm-badge]: https://img.shields.io/npm/v/libphonenumber-js.svg?style=flat-square [travis]: https://travis-ci.org/halt-hammerzeit/libphonenumber-js [travis-badge]: https://img.shields.io/travis/halt-hammerzeit/libphonenumber-js/master.svg?style=flat-square [coveralls]: https://coveralls.io/r/halt-hammerzeit/libphonenumber-js?branch=master [coveralls-badge]: https://img.shields.io/coveralls/halt-hammerzeit/libphonenumber-js/master.svg?style=flat-square