DEV Community

Jonas Hämmerle
Jonas Hämmerle

Posted on

Stop using regex for phone validation - use this instead

A regex for "valid phone number" is a trap. International phone numbering isn't regular: number length, valid area codes, and mobile-vs-landline prefixes differ per country and change over time as ranges get reassigned. A regex that's correct today starts silently misclassifying numbers months later, and you won't notice until a support ticket comes in.

The actual fix is using the numbering-plan data Google publishes and maintains for Android/Chrome: libphonenumber, or its much smaller JS port libphonenumber-js.

import { parsePhoneNumberFromString } from "libphonenumber-js";

const phone = parsePhoneNumberFromString("+49 30 1234567");
phone?.isValid();              // true - checks length + pattern for that country
phone?.country;                // "DE"
phone?.getType();               // "FIXED_LINE" | "MOBILE" | undefined (not always determinable)
phone?.formatInternational();   // "+49 30 1234567", normalized
Enter fullscreen mode Exit fullscreen mode

Two things regex can't give you that this does for free:

  • Country-aware validity. "Valid length" isn't one number — it varies by country and sometimes by number type within a country. The library knows the real ranges, and gets updated when they change.
  • Normalization. Users type phone numbers a dozen different ways (spaces, dashes, parens, with or without country code). formatInternational() gives you one canonical form to store and compare against, instead of writing your own normalization pass.

One gotcha: without a country hint, a local-format number is ambiguous. 030 1234567 is valid in Germany and might also just be a truncated something-else from another country. If your form is scoped to one country, pass it as the default country rather than relying purely on a + prefix being present.

If your backend isn't JS (or you don't want the dependency in a small service), I wrapped libphonenumber-js as a hosted endpoint on Validate — same validation logic, plain JSON in and out.

Top comments (2)

Collapse
 
topstar_ai profile image
Luis

Great advice. Phone numbers are a classic example of where regex quickly breaks down. International formats, country-specific rules, extensions, and formatting differences make it nearly impossible to maintain a reliable regex-based solution.

Using a library that understands real numbering plans is much more robust and easier to maintain. It also helps separate validation from formatting, making applications more reliable as they expand to new regions.

This is a great reminder that sometimes the best engineering decision is to rely on well-tested domain libraries instead of reinventing complex standards yourself.

Collapse
 
frank_signorini profile image
Frank

Have you considered using libphonenumber for more robust validation, or is there a specific reason to avoid it? I'd love to swap ideas on this, following for more content on validation best practices.