google-libphonenumber for Node.js: parsing, validation, and formatting
The up-to-date and reliable Google's libphonenumber package for node.js.
At a glance
- What is it?
- google-libphonenumber packages Google's phone number metadata for direct use in Node.js, with parsing, validation, formatting, and incremental input support. It simplifies integration of the Closure-coupled JavaScript port, but leaves TypeScript declarations to a separate package.
- Who is it for?
- Adopt google-libphonenumber for Node.js services or CLIs that need Google's parsing, validation, metadata, and phone number formatting without assembling the Closure-based port manually. Do not choose it if bundled TypeScript declarations or direct control over the generated distribution are requirements.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why google-libphonenumber exists for Node.js
google-libphonenumber addresses a packaging gap around Google's libphonenumber JavaScript port. The README says Google's implementation compiles to Java, C++, and JavaScript, but the JavaScript version is tightly coupled to Google Closure Library. That coupling makes it difficult to require and use the original code directly in a Node.js project.
The package is aimed at developers who need phone number operations in Node.js applications, command-line tools, or server-side services. It can parse international phone numbers, test whether numbers are possible or valid, identify regions and number types, format numbers in several styles, and preserve raw input. The repository describes Google libphonenumber as backed by carrier metadata, but it does not claim that every number entered into an application will pass validation.
Its primary distinction is packaging. The README says Google's libphonenumber was still not officially available on NPM, while this repository provides the functionality as `google-libphonenumber`. Consumers can require a packaged Node.js module instead of manually reconciling the upstream JavaScript source with Google Closure Library.
This is infrastructure for handling identity and routing data. A checkout flow can normalize an address-book value, a notification system can render a number for a known region, or an internal tool can reject an invalid regional number before storage. The documented checks do not establish that a number is currently assigned, reachable, owned by a particular person, or suitable for an SMS campaign. They concern parsing, number patterns, regions, types, and formatting.
How PhoneNumberUtil handles parsing and validation
The central object is `PhoneNumberUtil`, obtained through `PhoneNumberUtil.getInstance()`. A raw string is first passed to `phoneUtil.parse` or `phoneUtil.parseAndKeepRawInput`, with a default region supplied when the string does not contain enough international context. That produces a `libphonenumber.PhoneNumber` instance containing structured fields rather than leaving the application to split digits, punctuation, and country information itself.
The parsed object exposes fields such as the country calling code, national number, extension, country-code source, Italian leading zero, and raw input. The README's US example reports country code `1`, national number `2024561414`, and country-code source `FROM_DEFAULT_COUNTRY`. The raw input remains `202-456-1414` when `parseAndKeepRawInput` is used.
The utility then accepts that object for several different checks. `isPossibleNumber` tests whether the number is structurally possible, `isValidNumber` tests whether it matches a valid pattern, and `isValidNumberForRegion` checks validity for a specified region. `getRegionCodeForNumber` returns the region associated with a number, while `getNumberType` identifies its documented type. For the README's example, the results are `true`, `true`, `true`, `US`, and `FIXED_LINE_OR_MOBILE`.
The object contract is important. Most libphonenumber functions expect a `PhoneNumber` instance, not a string. Passing raw text directly to `isValidNumberForRegion` can produce `TypeError: a.getCountryCodeOrDefault is not a function`. A service should centralize parsing and pass the parsed object to every later operation rather than scattering string-to-phone-number conversion across request handlers.
Installing google-libphonenumber and running a first parse
The README documents installation through NPM. This command adds the runtime package as a production dependency:
npm install --save-prod google-libphonenumberThe package does not ship TypeScript definitions. The README points to the community-maintained `@types/google-libphonenumber` package for TypeScript projects:
npm install --save-dev @types/google-libphonenumberThe first use should create the utility and parse the raw string before calling validation or formatting methods. This follows the README's US example:
const PNF = require('google-libphonenumber').PhoneNumberFormat;
const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();
const number = phoneUtil.parseAndKeepRawInput('202-456-1414', 'US');The resulting object is the input required by most utility functions. It can now be checked and converted to a normalized representation:
console.log(phoneUtil.isValidNumberForRegion(number, 'US'));
console.log(phoneUtil.format(number, PNF.E164));The README's documented output for this example is `true` followed by `+12024561414`. The same pattern applies to `isValidNumber`, `getRegionCodeForNumber`, `getNumberType`, and the other formatting methods.
PhoneNumberFormat output modes for stored numbers
Once a number has been parsed, `PhoneNumberFormat` supplies the output modes for `phoneUtil.format`. The README documents `E164`, `NATIONAL`, and `INTERNATIONAL`, and shows how the same parsed US number changes across those modes. E164 produces `+12024561414`, national formatting produces `(202) 456-1414`, and international formatting produces `+1 202-456-1414`.
Two additional methods handle context that is not represented by a single format constant. `formatInOriginalFormat` uses the original format from which the number was parsed. In the example, it returns `(202) 456-1414` when the source region is `US`. `formatOutOfCountryCallingNumber` takes the region from which the number will be dialed, producing different strings for US and Swiss calling contexts.
This distinction is useful in applications that store one normalized value but present different text to different audiences. A backend can retain an E164 representation while the interface renders a national form for local users or an international form for support staff. The README does not describe storage recommendations, however, so teams should decide separately whether to store the original input, the parsed object, or a canonical string.
Formatting is not a substitute for validation. A string can be formatted according to a region's rules while failing a validity or region-specific check. The API separates those concerns, so an application should not infer assignment or deliverability from punctuation and spacing in formatted output.
AsYouTypeFormatter state for incremental input
`AsYouTypeFormatter` is the package's specialized API for progressive phone number display. It is intended for an input field where formatting changes as the user enters characters. The caller creates one formatter for a default region and passes each input event to `inputDigit`.
The operation is stateful. The formatter accumulates input digits, so every keystroke must reach the same instance in the correct order. The README's `US` example sends `202-456-1414` one character at a time, including punctuation, and receives progressively formatted strings such as `2`, `20`, `202`, `202-`, and `202-456`. Once the complete value has been entered, the formatter reaches `202-456-1414`.
Calling `clear` removes all accumulated input digits from the instance. This allows the same formatter object to represent a new entry. Applications that reuse instances across form resets should call that method at the appropriate lifecycle point rather than assuming that constructing a new display string clears the formatter's internal state.
This API handles display feedback, not final validation. Intermediate strings can be incomplete, and the README does not define them as valid phone numbers. A form should keep the raw field value if it needs to submit exactly what the user entered, then parse and validate a completed value separately when the business logic requires it. Treating an `AsYouTypeFormatter` result as proof of validity would conflate presentation with data validation.
Package layout, licensing, releases, and upgrade cost
The `package.json` entry point is `dist/libphonenumber.js`, and the published `files` list contains only `dist`. The repository also includes `src/`, `bin/`, `build.xml`, `package-lock.json`, and `test/`, showing that consumers receive a generated distribution backed by a source and build tree. The README describes the package as having zero dependencies, while `devDependencies` include Browserify, Google Closure Compiler, Google Closure Library, Mocha, and ESLint for development.
The build lifecycle is explicit. `npm run build` calls `bin/build.sh`, `npm run update` calls `bin/update.sh`, and `npm test` runs the build before `testonly`. The `prepare` script runs the build during package preparation, while `version` runs the build and stages `dist`. Updating upstream phone number metadata or releasing a new package therefore involves generated output and build scripts, not only application-level source edits.
The `package.json` license field is `(MIT AND Apache-2.0)`. The repository description also points to a `LICENSE` file because GitHub classifies the license as custom. These records should be reviewed before redistribution, but they do not replace examining the repository's actual license text and determining which notices apply to a particular deployment.
The repository is not archived. Its last push was on 2026-10-14, and the recorded releases include `v3.2.47` on 2026-09-29, `v3.2.46` on 2026-07-30, and `v3.2.45` on 2026-07-30. The package declares Node.js `>=0.10` and marks `sideEffects` as false. Upgrade work for consumers is mostly dependency management, while contributor or maintainer upgrades also involve the build and generated `dist` files.
Limits of validation and the Closure-based alternative
The clearest integration limitation is the parsed-object requirement. Most methods need a `PhoneNumber` instance, while raw strings are accepted by parsing functions. Code that passes strings directly to validation or formatting APIs can fail with the documented `TypeError: a.getCountryCodeOrDefault is not a function`. The fix is architectural: define a parsing boundary and keep all downstream operations on the resulting object.
TypeScript is another constraint. The runtime package ships no declarations, so a TypeScript project needs `@types/google-libphonenumber` or its own types. Those declarations are maintained separately by the community, which means a team using this package must account for an additional compatibility surface rather than relying entirely on declarations shipped with the runtime release.
The validation scope is also narrower than contact verification. `isPossibleNumber`, `isValidNumber`, and `isValidNumberForRegion` test different structural and regional conditions. The README does not document SMS delivery checks, ownership verification, carrier assignment, or consent management. This package should be chosen for parsing, normalization, metadata, and formatting, not as a messaging deliverability service.
A real alternative is to assemble the original Google JavaScript port with Google Closure Library. That approach retains the upstream source and Closure relationship directly, but the README describes it as cumbersome for Node.js. google-libphonenumber chooses the opposite trade-off: a packaged `dist` entry with zero runtime dependencies. Choose the Closure-based route when direct control over the upstream build is more important than installation simplicity.
Editorial conclusion
Adopt google-libphonenumber for Node.js services or CLIs that need Google's parsing, validation, metadata, and phone number formatting without assembling the Closure-based port manually. Do not choose it if bundled TypeScript declarations or direct control over the generated distribution are requirements. Check `dist/libphonenumber.js`, the `LICENSE` file, the build scripts in `bin/`, and `@types/google-libphonenumber` before integration.
Frequently asked questions
How do I install google-libphonenumber for Node.js?
Install `google-libphonenumber` with `npm install --save-prod google-libphonenumber`. TypeScript projects can add the separately maintained declarations with `npm install --save-dev @types/google-libphonenumber`.
How do I validate a phone number with google-libphonenumber?
Parse the raw string with `phoneUtil.parse` or `phoneUtil.parseAndKeepRawInput`, then pass the resulting `PhoneNumber` object to `isValidNumber`, `isPossibleNumber`, or `isValidNumberForRegion`. Passing the raw string directly to most validation methods can throw a `TypeError`.
Does google-libphonenumber include TypeScript definitions?
No. The README says the package ships without type definitions and points to the community-maintained `@types/google-libphonenumber` package instead.
How does google-libphonenumber format phone numbers as a user types?
Create an `AsYouTypeFormatter` with a region, pass each input character to `inputDigit`, and use `clear` to reset the accumulated digits. The formatter is for progressive display and is separate from parsing and validating a complete number.
Is google-libphonenumber the original Google Closure Library implementation?
It packages Google's libphonenumber functionality for easier Node.js use. The README explains that the original JavaScript port is tightly coupled to Google Closure Library and that running it directly remains cumbersome.
Official sources
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.
[](https://hysenlabs.com/projects/ruimarinho-google-libphonenumber)Was this useful?