Skip to content
Devix Open Source
UI component v1.2.0 MIT Alpha

Phone Input

International phone field with as-you-type formatting, validation and lazy per-country metadata.

npm install @devix-labs/phone-input
Vanilla JS React Vue Svelte Angular jQuery Laravel WordPress
Basic Open

libphonenumber-grade validation for 254 regions, split per country so visitors download about half a kilobyte of rules. Zero dependencies, built-in flags that work on Windows, and wrappers for React, Vue, Svelte, web components and jQuery.

What you get

Validation you can trust

Google's libphonenumber metadata for 254 regions, every number type, and a specific reason for each rejection.

Half a kilobyte per country

Rules load per region on first use. The whole widget is about 17 KB — intl-tel-input with utils is 77 KB.

Edits like a text field

The caret stays with its digit, backspace over a space deletes a digit, and pasting any format just works.

Understands real input

Arabic-Indic, Persian and full-width digits, autofill, extensions, trunk prefixes and +1 area codes.

Every stack

Vanilla JS, React, Vue, Svelte, a form-associated web component and jQuery — plus a DOM-free core for servers.

Accessible and global

WAI-ARIA combobox, full keyboard, RTL, localized country names, and a bottom sheet on phones.

Wears your design system

Every part is a CSS variable, a class hook or your own icon — or keep your field exactly as it is with the overlay layout.

Why another phone input?

Because the popular ones make you choose. intl-tel-input validates well but downloads a 60 KB utils file. react-international-phone is small but validates with masks, so real numbers get rejected. Almost all of them fight you when you edit the middle of a number, lose the country when you paste, or fetch flags from someone else's CDN.

Devix Phone Input uses the same numbering-plan data as Google's libphonenumber, split per country so a visitor only downloads the rules they use, wrapped in an input that edits the way people expect.

import { createPhoneInput } from '@devix/phone-input';

const phone = createPhoneInput(document.querySelector('#phone'), { initialCountry: 'auto' });

phone.input.addEventListener('dx:phonechange', (event) => {
  const { e164, valid, reason, type } = event.detail;
});

What it handles for you

Situation What happens
Someone pastes +44 (0)7400 123456 Country switches to the UK, the (0) is dropped, value is +447400123456
Typing ٠٥٠١٢٣٤٥٦٧ on an Arabic keyboard Read as 0501234567 for the UAE
A US field receives a 204 area code Country follows to Canada — same +1, correct flag
Backspace right after a space Deletes the digit before it, not the space
+1 800 555 0199 ext. 22 Extension kept separately, number still valid
The number is short reason: "too_short", not just "invalid"

Validate on the server too

The core has no DOM, so the same rules run in Node, Bun, Deno, workers and edge functions:

import '@devix/phone-input/metadata/all';
import { inspect } from '@devix/phone-input/core';

inspect('+92 301 2345678').valid; // true

How it compares

Questions

How accurate is the validation?

It uses the same numbering-plan metadata as Google's libphonenumber. Our test suite validates every one of libphonenumber's 1,133 example numbers with the correct type, and round-trips each through three formats.

Does it make network requests?

Only for its own lazy chunks from wherever you host the package. There is no geo-IP call by default — country detection uses the device's time zone and language — and flags are built in.

Can I store the value?

Yes: getNumber() returns E.164 (+971501234567), the format every SMS and calling API expects.

Can I validate on the server?

Yes. Import @devix/phone-input/core with the metadata/all bundle in Node, Bun, Deno or an edge function, or use the Laravel Phone package, which reads the same metadata.

Is it free for commercial use?

Yes — MIT licensed. The compiled phone metadata is Apache-2.0, like libphonenumber itself.