SkillAgentSearch skills...

Phone

With a given country and phone number, validate and reformat the mobile phone number to the E.164 standard. The purpose of this is to allow us to send SMS to mobile phones only.

Install / Use

/learn @AfterShip/Phone
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Phone · PRs Welcome FOSSA Status

What is phone?

phone is used to normalize mobile phone numbers into E.164 format.

A common problem is that users normally input phone numbers in this way:

`(817) 569-8900` or
`817569-8900` or
`1(817) 569-8900` or
`+1(817) 569-8900` or ...

We always want:

+18175698900

Install

npm install phone

// or

yarn add phone

Usage

const {phone} = require('phone');

// or

import {phone} from 'phone';

1. Simple usage

phone('+852 6569-8900');
// { isValid: true, phoneNumber: '+85265698900',  countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

2. With Country

phone('+1(817) 569-8900', {country: ''}); 
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}

phone('(817) 569-8900', {country: 'USA'});
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}

phone('(817) 569-8900', {country: 'HKG'});
// { isValid: false }
// not a valid HKG mobile phone number

phone('+1(817) 569-8900', {country: 'HKG'});
// { isValid: false }
// not a valid HKG mobile phone number

phone('6123-6123', {country: 'HKG'});
// { isValid: true, phoneNumber: '+85261236123', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

3. Without country code and no phone prefix

If both country code and country phone prefix are not provided, the phone number will be treated as USA or Canada by default.

phone('(817) 569-8900');
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }

phone('(817) 569-8900', {country: ''});
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }

phone('780-569-8900', {country: null});
// { isValid: true, phoneNumber: '+17805698900', countryIso2: 'CA', countryIso3: 'CAN', countryCode: '+1' }
// 780 is a Canada phone prefix

phone('6123-6123', {country: null});
// { isValid: false }
// as default country is USA / CAN and the phone number does not fit such countries' rules

4. With country code / phone prefix, but no + sign

Even you input a valid phone number with a valid prefix, if there is no plus sign, it will not work as expected:

phone('85291234567');
// or
phone('85291234567', {country: null});

// { isValid: false }

852 is a valid Hong Kong phone prefix, and 91234567 is a valid Hong Kong mobile phone number. However, there is no plus sign provided, the module will assume the phone number is a USA or Canada phone number, hence no result will be found.

If you know you have provided country phone prefix, make sure you also provide a plus sign:

phone('+85291234567');
// or
phone('+85291234567', {country: null});

// { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

or, if you know the country, and only want to reformat the phone number to E.164 format:

phone('91234567',  {country: 'HKG'})
// { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

5. Skipping phone number initial digit checking

If you want to skip phone number initial digit checking, set validateMobilePrefix to false:

phone('+(852) 2356-4902');
// { isValid: false }
// '2' is a Hong Kong landline phone number prefix, not a valid mobile phone number prefix

phone('+(852) 2356-4902', {validateMobilePrefix: true});
// { isValid: false }
// same as above, default value of validateMobilePrefix = true

phone('+(852) 2356-4902', {validateMobilePrefix: false});
// { isValid: true, phoneNumber: '+85223564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
// skipping mobile prefix checking

With validateMobilePrefix set to false, the initial digit checking logic will be disabled completely, even you enter a phone number start with a non-exist digit:

phone('+(852) 0356-4902', {validateMobilePrefix: false});
// { isValid: true, phoneNumber: '+85203564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
// even the phone number start with `0` is not a valid landline phone number

Note that the module does not have the capability to determine if the prefix is a valid landline prefix number.

6. Trunk Code Detection Logic

For some phone numbers, such as this sample UK phone number:

+44 07911 123456

There is a trunk code 0 after the country code +44 so that it is unable to match any correct country.

Hence the module will try to remove 1 digit after the country code,

and try to detect:

+44 7911 123456

and it would become a valid UK phone number now.

phone('+4407911 123456')
// { isValid: true, phoneNumber: '+447911123456', countryIso2: 'GB', countryIso3: 'GBR', countryCode: '+44' }

If you want to disable this behavior, please set strictDetection to true:

phone('+4407911 123456', {strictDetection: true})
// { isValid: false }

API

const {phone} = require('phone');

// or

import {phone} from 'phone';

phone(phoneNumber: string, { country, validateMobilePrefix, strictDetection }?: {
    country?: string;
    validateMobilePrefix?: boolean;
    strictDetection?: boolean;
})

Input

Parameter | Type | Required | Default | Description --- | --- | --- | --- | --- phoneNumber | String | Yes | - | The phone number text you want to process country | String | No | null | Provided country code in iso-3166 alpha 2 or 3 format validateMobilePrefix | Boolean | No | true | Set to false if you want to skip phone number initial digit checking strictDetection | Boolean | No | false | Set to true if you want to disable trunk code detection logic.

Returns

type PhoneResult = PhoneInvalidResult | PhoneValidResult;

interface PhoneValidResult {
	isValid: true;
	phoneNumber: string;
	countryIso2: string;
	countryIso3: string;
	countryCode: string;
}

interface PhoneInvalidResult {
	isValid: false;
	phoneNumber: null;
	countryIso2: null;
	countryIso3: null;
	countryCode: null;
}

Parameter | Type | Description --- | --- | --- isValid | Boolean | To indicate if the result valid phoneNumber | String or null | Normalized phone number in E.164 format countryIso2 | String or null | Detected phone number country code in iso-3166 alpha 2 format countryIso3 | String or null | Detected phone number country code in iso-3166 alpha 3 format countryCode | String or null | Detected phone number country calling code with + sign

Test

yarn test

Interactive Web Example

yarn start:example

or

yarn dev

And then visit http://localhost:8080

Build

yarn build

FAQ

  1. Does phone do any logical validation?

    Yes. If you provide country, and the phone number does not start with a + sign, the module will validate both phone_number_lengths and mobile_begin_with

  2. Why is phone returning an invalid result for a valid phone number?

    By default, the function validates mobile phone numbers only. It checks the phone number prefix and length to determine validity. If you want to skip the mobile prefix validation (for example, when checking landline numbers), you can set validateMobilePrefix to false.

    Note: Disabling this check does not enable "landline mode". The library does not support landline number validation, as it only contains validation rules for mobile numbers. If a landline number has a different length or format than a mobile number, the library may not process it correctly.

    If you believe the result is incorrect, please submit a ticket to improve our validation rules.

  3. Why is phone returning an object with isValid = false instead of returning a null directly?

    Returning an object (with isValid = false) allows us to extend the response format in the future, making it more flexible for adding additional information about invalid results.

Migrate from v2

The interface of v3 has been changed for better usability, maintainability, and flexibility, this shows all the changes from v2:

Function Interface

Version | Interface --- | --- v2 | phone(phoneNumber, country, allowLandline) v3 | phone(phoneNumber,{country: String, validateMobilePrefix: Boolean, strictDetection: Boolean})

Function Response

Version | Result | Interface --- | --- | --- v2 | - | [phoneNumber, country] v3 | Valid | {isValid: true, phoneNumber: string, countryIso2: string, countryIso3: string, countryCode: string} v3 | Invalid | {isValid: false, phoneNumber: null, countryIso2: null, countryIso3: null, countryCode: null}

allowLandline vs validateMobilePrefix

allowLandline in v2 is essentially equal to validateMobilePrefix in v3, however, the value is the opposite.

Because allowLandline = true in v2 means "Skip the mobile phone number prefix validation", and there is NO capability to verify if the input phone

View on GitHub
GitHub Stars918
CategoryDevelopment
Updated1d ago
Forks287

Languages

TypeScript

Security Score

100/100

Audited on Apr 1, 2026

No findings