Library / SDK
google/libphonenumber avatar
google/libphonenumber

google/libphonenumber: parsing, formatting and validating international phone numbers in Java, C++ and JavaScript

Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers.

18,290 stars2,180 forksC++Apache-2.0

At a glance

What is it?
Google's libphonenumber is the metadata-driven phone number library behind Android's dialer. It handles parsing, formatting, validation, carrier and timezone lookup, and it ships as Java, C++ and JavaScript code under Apache-2.0.
Who is it for?
Adopt google/libphonenumber when you need one phone-number implementation shared across Java, C++ and JavaScript services and you can absorb fortnightly metadata releases. Do not adopt it if you only need a small browser bundle, or if you cannot take a dependency whose validation rules change on someone else's schedule.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What google/libphonenumber actually solves

Phone numbers look like strings and behave like structured data with per-country rules that change constantly. A number that is valid in one region is invalid in another, the same digits can be a fixed line or a mobile depending on prefix, and the correct national presentation differs from the dialable international one. google/libphonenumber encodes those rules as metadata and exposes them through one API in three languages.

The README describes it as "Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers", and notes that the Java version is optimised for smartphones and used by the Android framework since 4.0 (Ice Cream Sandwich). That provenance is the strongest argument for it: the same code path that validates a number on an Android device is available to your server.

It is for backend engineers who accept phone numbers from users in many countries, for client developers who need an as-you-type formatter, and for data teams that need to detect numbers inside free text. It is not a phone number database. It knows the shape of a number, not whether the number is assigned to anyone.

Metadata, PhoneNumber and the formatting pipeline

The mechanism is a two-stage design: compiled metadata plus a small set of operations over a PhoneNumber value object. The README states that PhoneNumber "was originally auto-generated from phonenumber.proto with necessary modifications for efficiency", and points readers to resources/phonenumber.proto for field meanings. The repository keeps the rule data in a top-level metadata/ directory, and making-metadata-changes.md documents how that data is edited.

Parsing takes a raw string plus a default region and returns that object. In the README example, parsing "044 668 18 00" with region "CH" yields country_code 41 and national_number 446681800. Everything downstream works on those two integers rather than on the original text, which is why formatting is deterministic.

Validation is deliberately split into two costs. isPossibleNumber uses only length information and is described as much faster than a full validation; isValidNumber does full validation for a region using length and prefix information. That split matters in request paths where you want to reject obvious junk before paying for a full check.

Around the core sit the classifiers: getNumberType distinguishes Fixed-line, Mobile, Toll-free, Premium Rate, Shared Cost, VoIP, Personal Numbers, UAN, Pager and Voicemail "whenever feasible"; isNumberMatch returns a confidence level that two numbers could be the same; PhoneNumberOfflineGeocoder, PhoneNumberToCarrierMapper and PhoneNumberToTimeZonesMapper attach geography, carrier and timezone. findNumbers locates numbers inside text, and AsYouTypeFormatter formats digits as the user types them.

Installing it and formatting a first number in Java

The README gives two routes for Java: integrate with Maven, with a link to the project wiki for the details, or download the latest jars from the Maven repository. The wiki is where the exact artifact coordinates live, so read it rather than copying a version string from a blog post. The published examples in the README use the package com.googlecode.libphonenumber.

Once the dependency is on the classpath, the whole first use is four lines. This parses a Swiss number, then formats it three ways:

java
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
PhoneNumber swissNumberProto = phoneUtil.parse("044 668 18 00", "CH");
boolean isValid = phoneUtil.isValidNumber(swissNumberProto);
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));

The README shows the expected outputs explicitly: INTERNATIONAL produces "+41 44 668 18 00", NATIONAL produces "044 668 18 00", and E164 produces "+41446681800". Store the E164 form. It is the only one of the three that is stable across display conventions.

For the JavaScript side, the README points at a demo that can be run at various tags, and the repository keeps the code under javascript/i18n/phonenumbers/. Note that the JavaScript demo link on master is served through htmlpreview, which is a convenience for reading the demo, not a distribution channel. For an actual npm package, the README does not name one; check what the javascript/ directory publishes before assuming the Google package and the widely used third-party package are the same thing.

If you want to see the library before wiring it into anything, the Java demo at libphonenumber.appspot.com is updated with a slight delay after the GitHub release, and the README records that the last demo update was v9.0.39. There is also a demo Android app, E.164 Formatter, in java/demoapp, described as an example of using the library in a real Android application.

Where the metadata model bites you

The library is only as correct as its metadata, and the metadata moves on a schedule you do not control. The README states that, excepting holidays and extenuating circumstances, releases happen fortnightly, and that sub-minor releases are published when a release contains only metadata changes. That is a real operational commitment: your dependency version is not a stable thing you set once.

Versioning follows the README's own rules. A major release means changes incompatible with the intent or specification of an existing API, or changes that force clients to modify code to keep building. A minor release means clients can adopt new functionality and would have to roll back if the release were marked bad. Everything else, including metadata-only changes, is sub-minor. So a jump from 9.0.38 to 9.0.39 can change which numbers your application accepts, without any code change on your side and without a minor version bump to warn you.

That has a concrete consequence. If you validate at write time and never re-validate, your stored data drifts from the current rules. If you re-validate on read, numbers that were accepted last quarter can start failing. Neither is wrong, but pick one deliberately.

The second limitation is scope. The classifiers are best-effort by design: getNumberType distinguishes mobile from fixed line "whenever feasible". Number portability means the prefix does not always tell you the current carrier or line type. PhoneNumberToCarrierMapper gives carrier information related to a number, not a guarantee about who operates it today.

Finally, porters are a separate audience with a separate risk. The README warns that some internal changes affect compatibility for porters without affecting clients, that these are announced on the libphonenumber-discuss mailing list, and that they are not reflected in the version number. If you maintain a port rather than consuming one, the version number is not a sufficient signal; the mailing list is.

libphonenumber-js and other ports: the real difference

The most common alternative people reach for is a port rather than a different design. A JavaScript rewrite such as libphonenumber-js reimplements the same metadata-driven approach in one language, typically with a smaller default bundle and a module layout built for bundlers. The trade-off is provenance and surface area: the Google repository is the source of the metadata and the reference behaviour, while a port tracks it on its own release cadence and may not implement every classifier, the geocoder, the carrier mapper or the timezone mapper.

That distinction matters more than bundle size in some cases. If you need findNumbers over free text, or offline geocoding, or you need the Java and JavaScript paths to agree exactly, a single-language port is the wrong centre of gravity. If you need a formatter in a browser bundle and nothing else, pulling in the whole Java-derived surface is overkill.

The same reasoning applies to other language bindings. The repository itself ships Java, C++ and JavaScript; anything else is a port maintained by someone else, with its own lag behind the metadata and its own list of implemented methods. The README's porter section is written precisely for the people maintaining those, which tells you the project treats them as a supported but separate track.

Licence, releases and the cost of staying current

The project is Apache-2.0. The repository root also contains a LICENSE.Chromium file alongside LICENSE, which is worth reading if you are redistributing the JavaScript build or the metadata, since the two files can cover different parts of the tree. This is a description of what is in the repository, not legal advice; route the question to your own counsel if you are embedding the metadata in a product.

Upgrade cost is dominated by metadata churn, not API churn. The README's own versioning rules exist to keep client code compiling across sub-minor releases, so the mechanical upgrade is usually a version bump. The work is in deciding when to take it and what to do about numbers that change validity.

There is one more practical wrinkle documented in the README: the Java demo lags the release, and the README notes a period where deployment issues prevented updating the Java demo with a new binary while the Maven release moved ahead, with a suggestion to use the JS demo in the meantime. If your team uses the hosted demo to sanity-check behaviour, do not assume it matches the artifact you just pulled.

For notification of releases, the README points to release tags, a release_notes.txt file in the repository, and the libphonenumber-discuss mailing list, which receives an announcement for every release.

Editorial conclusion

Adopt google/libphonenumber when you need one phone-number implementation shared across Java, C++ and JavaScript services and you can absorb fortnightly metadata releases. Do not adopt it if you only need a small browser bundle, or if you cannot take a dependency whose validation rules change on someone else's schedule. Before committing, verify three things: that your target language binding exists in the repository, that your release process can pick up sub-minor metadata versions without a code change, and that your stored numbers are normalised to E.164 so that a metadata update cannot silently invalidate them.

Frequently asked questions

Who maintains google/libphonenumber?

It is a Google project, published under the google organisation on GitHub, and the README states the Java version is used by the Android framework since 4.0 (Ice Cream Sandwich). The README directs contributors to CONTRIBUTING.md and announces releases on the libphonenumber-discuss mailing list.

Is google/libphonenumber open source and free to use?

Yes. The repository is licensed under Apache-2.0, with an additional LICENSE.Chromium file at the root covering other parts of the tree. The source for the Java, C++ and JavaScript implementations is in the repository.

How do I use google/libphonenumber in Java?

Add the dependency through Maven, following the project wiki, or download the jars from the Maven repository. Then call PhoneNumberUtil.getInstance(), parse the string with a default region, and format the resulting PhoneNumber with PhoneNumberFormat.INTERNATIONAL, NATIONAL or E164.

What is the difference between Google's libphonenumber and libphonenumber-js?

The Google repository ships Java, C++ and JavaScript implementations and is the source of the shared metadata. libphonenumber-js is a separate JavaScript project; the Google README does not document it, so verify which classifiers and mappers a port implements before relying on it for carrier, timezone or text-scanning behaviour.

How do I use libphonenumber in JavaScript?

The README points at a JavaScript demo that can be run at various tags, and the implementation lives under javascript/i18n/phonenumbers/ in the repository. The README does not name an npm package for the Google implementation, so check what that directory publishes before assuming a package name.

Is libphonenumber available on npm?

The README does not document an npm package for the Google implementation; it links a JavaScript demo and keeps the code under javascript/i18n/phonenumbers/. The widely used libphonenumber-js package is a separate project, not something the README describes.

Official sources

  1. google/libphonenumber on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-libphonenumber.svg)](https://hysenlabs.com/projects/google-libphonenumber)