nyaruka/phonenumbers: Go Phone Number Parsing and Validation
Go port of Google's libphonenumber library
At a glance
- What is it?
- nyaruka/phonenumbers is a Go port of Google's libphonenumber for parsing, validating, and formatting phone numbers. It tracks the Java implementation closely and embeds upstream metadata for region-aware number handling.
- Who is it for?
- Adopt nyaruka/phonenumbers when a Go service needs libphonenumber-compatible parsing, validation, or formatting and accepts the upstream library's metadata model. Do not adopt it for phone-number capabilities that libphonenumber does not provide, because this project explicitly rejects feature requests outside that scope.
- Can I use it commercially?
- Yes. MIT 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 3 days ago.
- What is it written in?
- Mainly Go, 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.
Star history
- nyaruka/phonenumbers1,607 ★ · +4
| Repository | 2026-10-16 | 2026-10-23 |
|---|---|---|
| nyaruka/phonenumbers | 1.6k | 1.6k |
4 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Why nyaruka/phonenumbers exists in Go services
nyaruka/phonenumbers addresses the problem of handling phone numbers as structured, region-dependent data rather than opaque strings. A number's meaning depends on the region supplied during parsing, and validation depends on libphonenumber's metadata and numbering rules. The project is aimed at Go developers who need these operations inside an application, service, or data-processing job. Its documented API includes parsing a number, checking whether it is valid for a region, and formatting it for display.
The project is a port of Google's libphonenumber, but it specifically tracks the Java implementation. That distinction matters for teams comparing behavior with other ports. The README says the C++ and JavaScript versions are themselves ports of the Java reference implementation. This repository is therefore intended to follow one upstream behavior closely rather than independently design a different phone-number model.
The library is for application logic, not user-interface formatting in the broad sense. For example, the usage example selects a national representation. The API also exposes files and packages associated with carrier information, geocoding, timezone data, alternate formats, short numbers, matching, and as-you-type formatting. Those repository components indicate a broader port surface, although the README does not document every public API or its operational requirements.
Parsing and validation depend on an explicit region
The core documented data flow starts with `phonenumbers.Parse`, which receives a string and a region code such as `"US"`. It returns a parsed number object and an error. The resulting object can then be passed to `phonenumbers.IsValidNumber` and to a formatter such as `phonenumbers.Format`.
This means the input string is not evaluated without geographic context. The region is part of the parsing call, not an optional afterthought in the example. A caller must decide what country context applies to the number. The README does not explain automatic region inference, fallback behavior, or how ambiguous international inputs are handled, so applications should not assume that a bare number can always be resolved from its digits alone.
The metadata is embedded in the library rather than loaded by the example application. The updating documentation names metadata categories including core territory metadata, short numbers, alternate formats, country-code-to-region mappings, carrier data, geocoding data, and timezone data. The generated release version is recorded in `metadata/version.go`. This gives a Go application a self-contained library surface, while also tying results to the metadata version selected by the project maintainers.
A minimal Go integration follows the README example
The README documents installation with the v2 module path. Add the dependency to the Go module before importing it. The command below is copied from the README and should be run in a Go project that already has a `go.mod` file.
% go get github.com/nyaruka/phonenumbers/v2The documented first use parses a number, validates it for its region, and formats it nationally. In a source file, import the v2 path exactly as shown, then call the three APIs in sequence.
import "github.com/nyaruka/phonenumbers/v2"
num, err := phonenumbers.Parse("8886418722", "US")
valid := phonenumbers.IsValidNumber(num)
formatted := phonenumbers.Format(num, phonenumbers.NATIONAL)The `err` value should be handled before relying on `num`. The README does not show the exact error type or a complete application-level error handler, so it does not establish how callers should display parse failures. After a successful parse, `valid` records whether the number is valid for the supplied region, while `formatted` contains the national representation returned by the selected formatter. The example is intentionally small, but it demonstrates the expected order of operations.
The metadata update process has a mechanical half
Maintaining the embedded data is separated from reconciling upstream Go code. The `buildmetadata` command clones an upstream release and rebuilds the gzipped metadata blobs embedded across the packages. The README lists the affected data groups and states that the command records the upstream release in the generated `metadata/version.go` file.
The default command resolves and builds from the latest upstream release. A specific upstream release tag can be supplied when reproducible selection is required. Both documented commands are reproduced below without adding flags or options that are not shown.
% go run ./cmd/buildmetadata% go run ./cmd/buildmetadata v9.0.31The first command is the normal path for resolving the latest upstream release. The second pins the metadata build to `v9.0.31`. Regeneration is described as automated, but it is not the complete synchronization procedure. The ported Go logic must also be reconciled with changes in the upstream Java implementation. That part requires judgment and is documented separately through `SYNC.md` and the `sync-upstream` skill. A dependency update can therefore involve more than changing a version number in application code.
Strict upstream parity limits feature expectations
The main constraint is explicit in the README: this is a strict port of libphonenumber, and the project does not accept feature requests for functionality that does not exist there. That policy makes behavior easier to compare with Google's reference implementation, but it also defines the boundary of the package. A Go developer looking for a Go-specific numbering policy, a different validation model, or a feature absent from libphonenumbers should not expect this project to supply it.
Unexpected parsing results are also treated as an upstream compatibility question first. The README instructs users to verify whether the same problem affects libphonenumber and, if so, report it there. It provides Google's online libphonenumber demo as a quick comparison point. That guidance matters because a surprising result may reflect libphonenumber's metadata or parsing rules rather than a defect specific to the Go port. The repository's package list shows tests and related components, but the repository documentation does not provide test commands or coverage figures.
The trade-off is deliberate: strict parity reduces conceptual drift from the Java reference, while feature requests are deferred to the upstream ecosystem. This is useful when cross-language consistency matters. It is a poor fit when the application needs a custom rule set that intentionally diverges from libphonenumber.
MIT licensing and release cadence still require upgrade planning
The repository identifies the project under the MIT license. That designation is relevant when integrating the package into a Go application, but the repository documentation does not provide legal interpretation or license text beyond the `LICENSE` file. The code should be reviewed under that file before distribution decisions are made.
The listed releases are `v1.8.1` from 2026-07-15, `v1.8.0` from 2026-06-01, and `v1.7.5` from 2026-05-25. The module path and repository structure include an `UPGRADING.md` file specifically for moving from 1.x to 2.x. That file is the relevant first source to inspect when an application changes major versions, because the README points users there but does not reproduce the migration steps.
The repository is not archived, and the last push was on 2026-10-02. Those facts describe repository state, but they do not establish the compatibility impact of every future metadata release. Upgrade work can include dependency changes, changes in embedded upstream metadata, and reconciliation of Go logic with upstream Java changes. The documented synchronization process makes that cost more visible than a simple package download.
A direct alternative is Google's libphonenumber through another language boundary
The closest documented alternative is to use Google's libphonenumber directly in a language whose implementation is already available, rather than choosing this Go port. The difference is not a different validation philosophy. The README describes nyaruka/phonenumbers as tracking the Java implementation of libphonenumber, while also noting that C++ and JavaScript versions are ports. A team already standardized on Google's Java implementation may prefer to call that implementation through an existing service boundary or use the Go package when native Go integration matters.
A different approach would be maintaining a custom parser or validation layer. That would allow application-specific rules, but the repository documentation provides no evidence about such an alternative's accuracy, maintenance burden, or metadata coverage. The meaningful comparison available here is therefore between Go integration through this port and using libphonenumber in its native or existing runtime. The choice depends on deployment language and consistency requirements, not on a claim that this project uses a separate numbering algorithm.
Editorial conclusion
Adopt nyaruka/phonenumbers when a Go service needs libphonenumber-compatible parsing, validation, or formatting and accepts the upstream library's metadata model. Do not adopt it for phone-number capabilities that libphonenumber does not provide, because this project explicitly rejects feature requests outside that scope. Before integration, verify the Go version, the v2 import path, and whether expected results match Google's online demo for representative numbers.
Frequently asked questions
How do I install nyaruka/phonenumbers in a Go project?
Run `go get github.com/nyaruka/phonenumbers/v2` as documented in the README. The module path includes `/v2`, so imports should use the same major-version path.
How do I parse and validate a phone number with nyaruka/phonenumbers?
Call `phonenumbers.Parse` with the number and a region such as `"US"`, check the returned error, then pass the parsed number to `phonenumbers.IsValidNumber`. `phonenumbers.Format` can format the parsed number using `phonenumbers.NATIONAL`.
Does nyaruka/phonenumbers support features that libphonenumber does not support?
No. The README calls the project a strict port of libphonenumber and says feature requests for functionality absent from that upstream library should not be submitted to this project.
How is the embedded phone-number metadata updated?
The `buildmetadata` command regenerates embedded metadata from an upstream release. The README documents using `go run ./cmd/buildmetadata` for the latest release or passing a release tag such as `v9.0.31`, while code reconciliation is a separate part of the synchronization process.
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/nyaruka-phonenumbers)Star history chart for your README
[](https://hysenlabs.com/projects/nyaruka-phonenumbers)Was this useful?