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.
Repository Health
Technical Analysis
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.
Used by 3 apps in this directory
Authgear
Authentication
Open-source, self-hostable authentication platform with passkeys, biometric login, SSO, MFA, and GraphQL admin API — a full Auth0/Clerk/Firebase alternative for SaaS and mobile apps.
EspoCRM
Marketing · Ecommerce · CRM
Open-source CRM platform with metadata-driven customization, field-level permissions, and a full REST API — deploy on your own infrastructure.
Khoj
AI Assistants · Knowledge Management · Productivity
A self-hostable AI second brain that chats with your documents, searches the web, builds custom agents, and runs entirely on your own LLM.