intl-tel-input

A JavaScript library that turns a plain text field into a country-aware phone number input, with official React, Vue, Angular, and Svelte components.

Library
npm
v29.2.3
8,251stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
91/100Excellent
Development Activity84
Maintenance96
Community84
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture88
Code Quality92
Innovation78
Learning Curve85

intl-tel-input attaches to a text input and gives it a searchable country dropdown with flags, auto-formats the number as the user types, and validates it against real per-country rules. It ships its own country/dial-code dataset and, when the optional utils module is loaded, delegates formatting and validation to a build of Google’s libphonenumber, so results match what phone carriers actually accept rather than a regex guess.

The core package is framework-agnostic vanilla JavaScript/TypeScript, and the same monorepo publishes thin official wrapper components for React, Vue, Angular, and Svelte so teams don’t have to hand-roll their own bindings. It includes translations for 50+ languages, RTL and alternative-numeral support, ARIA-friendly markup, and a large configurable surface (initial country detection, allowed countries, number type restrictions, placeholder policy) covering most real-world phone-capture requirements out of the box.

What You Get

  • A searchable country dropdown with flags, dial codes, and full keyboard navigation
  • Auto-detection of the user’s country and per-country example placeholders
  • As-you-type formatting plus E.164 extraction for storage, via an optional libphonenumber-powered utils module
  • Typed validation with specific error reasons (too short, too long, invalid country code, etc.)
  • Official framework components for React, Vue, Angular, and Svelte built on the same core
  • Translations into 50+ languages with RTL and alternative-numeral support

Common Use Cases

  • Signup and checkout forms that need a normalized, validated phone number
  • SMS/2FA verification flows that require a correctly formatted number before sending a code
  • Multi-country SaaS onboarding forms where users self-select their country
  • Any form migrating from a free-text phone field to structured, validated input

Under The Hood

Architecture The library is organized as a small monorepo: packages/core holds the framework-agnostic engine (intlTelInput.ts, ~1800 lines, orchestrating instance lifecycle, option normalization via core/options.ts, and DOM rendering via core/ui.ts, ~1400 lines), with focused modules split out for country search (core/countrySearch.ts), numeral handling (core/numerals.ts), as-you-type caret math (format/caret.ts), and dial-code/regionless-number edge cases (data/nanp-regionless.ts, data/intl-regionless.ts). Each instance is tracked by an incrementing id rather than a shared singleton, so multiple inputs on one page stay isolated; a lazily-loaded utils module (loaded on demand, referenced through a UtilsLoader type) keeps the heavyweight libphonenumber logic out of the base bundle until formatting/validation is actually needed. packages/react, packages/vue, packages/angular, and packages/svelte are thin wrapper packages that instantiate the same core engine rather than reimplementing behavior, so all frameworks share one source of truth for formatting and validation rules.

Tech Stack Written in TypeScript throughout the core and all framework packages, built with esbuild for the JS bundle and a dedicated scripts/esbuild-css.js/build-dts.js pipeline for CSS and hand-assembled .d.ts output. The country/dial-code dataset and formatting logic are generated at build time from Google’s libphonenumber and mledoze’s world-countries data, with flag assets sourced from the flag-icons project. Framework components are built against current major versions (Angular 21, React 19, Vue’s vue-tsc, Svelte with svelte-check), each compiled and type-checked as an independent package output.

Code Quality The repo runs a large, layered test suite: unit tests (Vitest) cover core modules like options, ui, countrySearch, numerals, formatting, and the country/regionless data files; a separate integration suite exercises dozens of individual configuration options end-to-end (tests/integration/options/*); and a further Playwright e2e suite covers real browser behavior, run both locally and via a Linux Docker harness for consistent screenshots. ESLint (flat config, typescript-eslint recommended) and Prettier are wired in, TypeScript runs in strict mode with a dedicated .d.ts typecheck step (build:js:dts:check) to guarantee published types match source, and GitHub Actions CI runs the full build-and-test matrix on push and PR.

What Makes It Unique Unlike most phone-input widgets that only regex-validate a dial code, this library builds its formatting and validation directly on a real libphonenumber port, so per-country number-length and format rules are authoritative rather than approximate, while keeping that dependency optional and lazily loaded to avoid bloating the base bundle. Maintaining first-party (not community-forked) wrapper packages for four separate frontend frameworks from one shared core, with a dedicated .d.ts consistency check across all of them, is a level of cross-framework parity investment uncommon for a UI input library of this size.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search