Skip to content
Devix Open Source

Guide

Getting started

Turn any <input> into an international phone field in three steps.

1. Install

npm install @devix-labs/phone-input

Or, with no build step, load it from the CDN as an ES module:

<link rel="stylesheet" href="https://www.devix.pk/cdn/oss/phone-input@1.2.0/phone-input.min.css">
<script type="module">
  import { createPhoneInput } from 'https://www.devix.pk/cdn/oss/phone-input@1.2.0/index.js';
  createPhoneInput(document.querySelector('#phone'));
</script>

2. Add the field

<label for="phone">Phone</label>
<input id="phone" name="phone">

Keep your own <label> — the widget announces the selected country alongside it.

3. Create it

import { createPhoneInput } from '@devix-labs/phone-input';
import '@devix-labs/phone-input/styles.css';

const phone = createPhoneInput(document.getElementById('phone'), {
  initialCountry: 'auto',            // time zone + language, no network request
  preferredCountries: ['ae', 'sa', 'pk'],
  hiddenInput: 'phone_e164',         // posts "+971501234567" with the form
});

Read the number

phone.getNumber();                 // "+971501234567" (E.164), or null while incomplete
phone.getNumber('INTERNATIONAL');  // "+971 50 123 4567"
phone.getNumber('NATIONAL');       // "050 123 4567"
phone.isValid();                   // true
phone.getValidationReason();       // "valid" | "too_short" | "too_long" | …

Or listen for changes:

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

No event fires when the widget first mounts — only when the number actually changes — so forms don't start out "dirty".

Updated 15 Sep 2026