Mateen Kiani
Published on Fri Jun 27 2025·4 min read
Phone numbers power user sign-ups, contact forms, and two-factor auth flows in modern web apps. Yet many developers focus on display widgets and overlook the crucial step of normalization—stripping out spaces, dashes, and parentheses before processing. How do you ensure consistent formatting across your app and avoid validation headaches?
The answer lies in combining simple functions, regex patterns, and proven libraries to standardize numbers at input, before storage, and on display. Understanding these techniques will help you prevent user errors, streamline backend checks, and deliver a polished user experience.
Before formatting, phone numbers must be normalized. Users paste numbers from different sources: “(123) 456-7890”, “123.456.7890”, or even “+1 123 456 7890”. Without stripping out non-digits, your validation logic may fail or store inconsistent data.
A good workflow:
Standardization helps:
One of the quickest ways to format phone numbers is with a regex replace. Here’s a simple US formatter:
function formatUS(number) {// Remove all non-digit charsconst digits = number.replace(/\D/g, '');// Apply (XXX) XXX-XXXX formatreturn digits.replace(/^(1)?(\d{3})(\d{3})(\d{4})$/, (m, country, a, b, c) => {const prefix = country ? '+1 ' : '';return `${prefix}(${a}) ${b}-${c}`;});}console.log(formatUS('123-456-7890')); // (123) 456-7890
Key points:
replace(/\D/g, '')
to strip non-digits.For global support, roll your own regex isn’t enough. Google’s libphonenumber-js handles countless formats, country codes, and validation rules. It’s the de facto standard in many production apps.
Top options:
Installation:
npm install libphonenumber-js
Basic usage:
import { parsePhoneNumberFromString } from 'libphonenumber-js';const phone = parsePhoneNumberFromString('+1 213 373 4253');console.log(phone.formatInternational()); // +1 213 373 4253console.log(phone.formatNational()); // (213) 373-4253
Tip: You can auto-detect the user’s locale and format accordingly.
Users love seeing their number take shape as they type. Attach an input listener and reformat on each keystroke:
<input id="phone" type="tel" placeholder="Enter phone number" />
const input = document.getElementById('phone');input.addEventListener('input', (e) => {const { selectionStart } = e.target;const raw = e.target.value.replace(/\D/g, '');const formatted = raw.replace(/(\d{3})(\d{1,3})?(\d{1,4})?/, (_, a, b, c) => {let out = a;if (b) out += `-${b}`;if (c) out += `-${c}`;return out;});e.target.value = formatted;e.target.setSelectionRange(selectionStart, selectionStart);});
Keep the cursor position by saving and restoring selectionStart
. This creates a smooth typing experience.
After cleaning, ensure the digit count matches your region. For US numbers:
function isValidUS(number) {const digits = number.replace(/\D/g, '');return /^(1?\d{10})$/.test(digits);}
Using tools like checking digit count can help you learn patterns for string/array length checks.
Bulletproof validation often combines regex, length checks, and library calls if you support international formats.
E.164 is the international standard for phone numbers. It guarantees global uniqueness and starts with “+” followed by country code and subscriber number, all as digits.
function formatE164(number) {const digits = number.replace(/\D/g, '');// Ensure leading '+' and country codereturn '+' + digits;}
Many APIs (Twilio, AWS SNS) require E.164 for sending SMS or calls.
Proper formatting improves data integrity, user trust, and compliance with telephony providers.
Formatting phone numbers in JavaScript can be as simple as a regex replace or as powerful as a full-blown library. By normalizing input, validating digit counts, and choosing the right display pattern, you’ll reduce errors and streamline your data flow. Real-time formatting boosts user trust, while E.164 ensures seamless integration with global APIs. Start small with regex for your primary region, then adopt a library when you need worldwide support. Consistency is key: centralize your logic, write unit tests, and cover edge cases. Armed with these tips, you’re ready to make phone inputs rock-solid in your next project.