Searching for a phone number regex gives you a hundred patterns and none of them is right for every country. This guide shows what a regex can and cannot do, and when a library like libphonenumber-js is worth the extra bytes.
The simple regex and where it breaks
A common pattern accepts ten digits. It works for one country and rejects everyone else.
const re = /^\d{10}$/
re.test('4155552671') // true
re.test('+14155552671') // false: the plus sign breaks it
re.test('020 7946 0958') // false: spaces break it
re.test('0000000000') // true: not a real number
// The library for the same input, with default country US:
parsePhoneNumberFromString('0000000000', 'US').isPossible() // true (the length fits)
parsePhoneNumberFromString('0000000000', 'US').isValid() // false (no such range exists)A generic E.164 regex
If you only need to check the shape of a number that is already in E.164 form, this is a reasonable minimum.
const e164 = /^\+[1-9]\d{1,14}$/
e164.test('+442079460958') // true
e164.test('+0442079460958') // falseWhy a per-country regex is better, and still not enough
The regex tool on this site gives you the pattern for each country from libphonenumber's data. It checks the length and prefix for that one country. It does not clean up input, tell you the number type or format the number, and it goes out of date when numbering plans change.
What a library adds
libphonenumber-js reads messy input, works out the country, and validates against up-to-date rules. It also gives you the E.164 value to store and the formats to show.
import { parsePhoneNumberFromString } from 'libphonenumber-js'
const phone = parsePhoneNumberFromString('020 7946 0958', 'GB')
phone.isValid() // true
phone.number // '+442079460958'isValid() or isPossible()
The library gives you two checks. isPossible() checks only that the length fits the country. isValid() also checks the digits against the assigned ranges. The library's author prefers isPossible() for forms, because numbering plans change and an old copy of the library could reject a new range. Use isValid() when the cost of a wrong number is high.
A practical rule
Use a regex for a quick shape check in a form, or in code that cannot take a dependency. Use a library when the number matters, for example before sending an SMS, saving it to a database or charging for verification.