react-intl-tel-input vs react-phone-input-2 vs react-phone-number-input
International Phone Number Input Components for React
react-intl-tel-inputreact-phone-input-2react-phone-number-input

International Phone Number Input Components for React

react-intl-tel-input, react-phone-input-2, and react-phone-number-input are React components designed to handle international phone number input in web forms. They provide country selection via flag dropdowns, automatic formatting as users type, and varying levels of validation. These libraries help developers collect correctly formatted phone numbers from users worldwide while improving UX through visual cues and real-time feedback.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-intl-tel-input38,251286256 kB834 years agoMIT
react-phone-input-201,015426 kB276-MIT
react-phone-number-input0-10.1 MB-4 days agoMIT

International Phone Input Components for React: A Deep Technical Comparison

When building forms that collect phone numbers from users around the world, you need more than a basic <input type="tel">. You need country-aware formatting, validation, and a clean UX. The three main React libraries for this — react-intl-tel-input, react-phone-input-2, and react-phone-number-input — each take a different approach. Let’s compare them in real-world terms.

📱 Core UX: How Users Interact with the Input

react-intl-tel-input shows a flag dropdown next to the input. Users pick a country, and the input auto-formats as they type based on that country’s rules.

import IntlTelInput from 'react-intl-tel-input';
import 'react-intl-tel-input/dist/main.css';

function MyForm() {
  return (
    <IntlTelInput
      preferredCountries={['us', 'gb']}
      onPhoneNumberChange={(isValid, value, countryData) => {
        console.log('Phone:', value, 'Valid:', isValid);
      }}
    />
  );
}

react-phone-input-2 also uses a flag dropdown but includes search functionality inside the dropdown. It updates the input with the selected country code and formats as you type.

import PhoneInput from 'react-phone-input-2';
import 'react-phone-input-2/lib/style.css';

function MyForm() {
  const [phone, setPhone] = useState('');

  return (
    <PhoneInput
      country={'us'}
      value={phone}
      onChange={setPhone}
      enableSearch={true}
    />
  );
}

react-phone-number-input (by catamphetamine) takes a minimalist approach. It renders a standard input with optional country selector, but focuses heavily on correctness using Google’s libphonenumber under the hood.

import { PhoneInput } from 'react-phone-number-input';
import 'react-phone-number-input/style.css';

function MyForm() {
  const [value, setValue] = useState();

  return (
    <PhoneInput
      placeholder="Enter phone number"
      value={value}
      onChange={setValue}
    />
  );
}

🔢 Validation and Formatting: What’s Under the Hood

react-intl-tel-input uses an older version of libphonenumber via intl-tel-input (its jQuery-based inspiration). It validates and formats based on the selected country, but doesn’t always handle ambiguous or incomplete numbers robustly.

react-phone-input-2 does not use libphonenumber. Instead, it relies on its own internal list of country codes and basic regex patterns. This means it can format numbers nicely but cannot validate them accurately — especially for countries with complex numbering plans.

// react-phone-input-2 gives you the raw string
// You must validate separately if you need accuracy
<PhoneInput
  onChange={(value, country) => {
    // value = "1234567890" (unformatted, no validation)
    // country = { name: "United States", dialCode: "1", ... }
  }}
/>

react-phone-number-input is built directly on top of Google’s libphonenumber (via libphonenumber-js). It parses, validates, and formats numbers according to official telecom standards. It returns E.164 formatted numbers by default, which are ideal for backend storage.

// react-phone-number-input gives you a validated, normalized number
<PhoneInput
  onChange={(value) => {
    // value = "+12133734253" (E.164 format, guaranteed valid if present)
  }}
/>

// You can also check validity explicitly
import { isValidPhoneNumber } from 'react-phone-number-input';
console.log(isValidPhoneNumber('+12133734253')); // true

🌍 Country Selection and Customization

All three support customizing the list of countries, but with different APIs.

react-intl-tel-input uses preferredCountries and onlyCountries:

<IntlTelInput
  onlyCountries={['us', 'ca', 'mx']}
  preferredCountries={['us']}
/>

react-phone-input-2 uses onlyCountries and preferredCountries (same names, different format):

<PhoneInput
  onlyCountries={['us', 'ca', 'mx']}
  preferredCountries={['us']}
/>

react-phone-number-input uses the countryOptionsOrder and countries props, but more commonly you control availability via the defaultCountry and user input:

<PhoneInput
  defaultCountry="US"
  // To restrict countries, you'd need to pass a custom list
  // See docs for advanced usage with countrySelectComponent
/>

Note: react-phone-number-input also supports disabling the country selector entirely if your app only serves one region.

⚙️ Integration with Form Libraries (React Hook Form, Formik)

react-intl-tel-input requires manual wiring because it doesn’t expose a standard value/onChange API. You’ll need to manage state carefully.

react-phone-input-2 works out of the box with most form libraries because it uses a familiar value/onChange pattern.

// With React Hook Form
const { register, setValue } = useForm();

<PhoneInput
  {...register('phone')}
  onChange={(value) => setValue('phone', value)}
/>

react-phone-number-input integrates cleanly because it behaves like a controlled input and returns standardized values:

// With React Hook Form
<Controller
  name="phone"
  control={control}
  render={({ field }) => <PhoneInput {...field} />}
/>

🛑 Maintenance Status and Deprecation Warnings

As of 2024:

  • react-intl-tel-input is deprecated. Its npm page states: “This package is no longer maintained. Please use react-phone-number-input instead.” Do not use it in new projects.
  • react-phone-input-2 is actively maintained and widely used, but lacks deep validation.
  • react-phone-number-input is actively maintained, follows modern React practices, and is recommended by experts for correctness-critical applications.

🧪 Real-World Tradeoffs: When to Use Which

Scenario 1: You Need Accurate Validation (e.g., SMS Login, User Verification)

  • Use react-phone-number-input
  • Why? Only it guarantees E.164 compliance and uses libphonenumber for true validation.

Scenario 2: You Want a Familiar UI with Minimal Setup (e.g., Contact Form)

  • Use react-phone-input-2
  • Why? It’s easy to drop in, looks polished, and works well for non-critical inputs where “good enough” formatting suffices.

Scenario 3: You’re Maintaining Legacy Code

  • ⚠️ If you already use react-intl-tel-input, plan a migration to react-phone-number-input.
  • Do not start new projects with it.

📊 Summary Table

Featurereact-intl-tel-inputreact-phone-input-2react-phone-number-input
Maintenance Status❌ Deprecated✅ Active✅ Active
Validation EngineOlder libphonenumberCustom regex (no validation)Google’s libphonenumber
Output FormatRaw or formatted stringRaw international stringE.164 (standardized)
Form Library Friendly❌ Manual integration✅ Yes✅ Yes
Country Search❌ No✅ Yes✅ (via prop)
Recommended for New Apps❌ Never✅ For simple use cases✅ For validation-critical apps

💡 Final Recommendation

If you care about correctness — especially for features like two-factor authentication, SMS notifications, or user identity — use react-phone-number-input. It’s the only one that guarantees your phone numbers are valid and properly formatted according to global standards.

If you’re building a marketing contact form where perfect validation isn’t critical and you want something that looks good fast, react-phone-input-2 is a reasonable choice.

And never start a new project with react-intl-tel-input — its deprecation notice is clear, and better alternatives exist.

How to Choose: react-intl-tel-input vs react-phone-input-2 vs react-phone-number-input

  • react-intl-tel-input:

    Do not use react-intl-tel-input in new projects — it is officially deprecated according to its npm page. If you encounter it in legacy code, plan a migration to a maintained alternative like react-phone-number-input. Its outdated dependencies and lack of active maintenance make it unsuitable for modern applications.

  • react-phone-input-2:

    Choose react-phone-input-2 when you need a visually polished, easy-to-integrate phone input with country search and minimal setup. It’s well-suited for non-critical forms like contact pages where strict validation isn’t required. However, avoid it if you need guaranteed phone number correctness, as it lacks true validation based on telecom standards.

  • react-phone-number-input:

    Choose react-phone-number-input when data accuracy and compliance matter — such as for SMS login, user verification, or any system requiring E.164-formatted numbers. It leverages Google’s libphonenumber for robust parsing and validation, integrates cleanly with modern React form libraries, and is actively maintained. It’s the best choice for production applications where phone number integrity is essential.

README for react-intl-tel-input

React-Intl-Tel-Input

PRs Welcome CICD npm version Coverage Status npm

NPM

Rewrite International Telephone Input in React.js.

Collaborators Wanted!

Due to the long commuting time, I do not have much time to maintain this project often. 😣

So if anybody else is willing to take on the work of bug fixes, integrating pull requests, etc, please let me know. 🙌

I hope we can maintain the project together, and make this project better! 💪

Demo & Examples

Live demo: patw0929.github.io/react-intl-tel-input

To build the examples locally, run:

yarn
yarn website:start

Then open localhost:3000 in a browser.

Installation

yarn add react-intl-tel-input

TypeScript

react-intl-tel-input ships with official type declarations out of the box.

Usage

import IntlTelInput from 'react-intl-tel-input';
import 'react-intl-tel-input/dist/main.css';

<IntlTelInput
  containerClassName="intl-tel-input"
  inputClassName="form-control"
/>

Properties

Please see the Demo Page

Development (src and the build process)

To build, watch and serve the examples (which will also watch the component source), run yarn website:start.

You can prepare a distribution build using yarn build.

Contributing

Any kind of contribution including proposals, doc improvements, enhancements, bug fixes are always welcome.

To contribute to react-intl-tel-input, clone this repo locally and commit your code on a separate branch. Please write tests for your code, and run the linter before opening a pull-request:

yarn test    # if you are enhancing the JavaScript modules
yarn test:ts # if you are enhancing the TypeScript type declarations
yarn lint

Also, please let us know if you encounter any issue by filing an issue.

Inspired by

International Telephone Input - @jackocnr

License

MIT

Copyright (c) 2015-2019 patw.