Phonelib: A Ruby Gem for Phone Validation That Stays Close to libphonenumber
Ruby gem for phone validation and formatting using google libphonenumber library data
At a glance
- What is it?
- Phonelib brings Google's libphonenumber data into Ruby, offering validation, formatting, and ActiveRecord integration. It covers common cases well but stops short of the full Google library, which matters for edge cases.
- Who is it for?
- Adopt Phonelib if you need straightforward phone validation and formatting in a Ruby or Rails app and you accept that it does not implement every libphonenumber feature. Skip it if you require the full Google library, such as carrier or timezone lookup, or if you need to handle obscure numbering plans that the gem's data does not cover.
- 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 2 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Star history
- daddyz/phonelib1,164 ★ · +1
| Repository | 2026-08-24 | 2026-10-22 |
|---|---|---|
| daddyz/phonelib | 1.2k | 1.2k |
1 Stars in the last 59 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What Phonelib Solves and Who Needs It
Phonelib answers a narrow but common problem: validating and formatting phone numbers in Ruby without reimplementing the world's numbering plans. The gem wraps Google's libphonenumber data, so you get country detection, validation against national patterns, and formatting to E.164 or national format. The intended user is a Rails developer who needs to check user input, whether from signup forms, contact fields, or SMS gateways. The README positions it for Rails 3.1 and up, and it ships an ActiveRecord validator out of the box. If your app only needs to know 'is this a valid number for country X' and 'what does it look like in E.164', Phonelib is a direct fit. It does not aim to be a full telephony toolkit, and the README says so plainly: it does not include all of Google's functionality.
How the Gem Uses libphonenumber Data
The core mechanism is data-driven. Phonelib loads the same metadata that Google's libphonenumber uses, which contains the regex patterns, country codes, and formatting rules for the world. When you call a validation method, the gem parses the input string, tries to infer a country, and matches the number against the stored patterns. The README shows that you can set one or several default countries, which the parser uses when the number does not start with a plus sign. If the number starts with '+', the gem attempts to detect the country from the dialing prefix, and it can reset the country if the provided default does not match the prefix. The data is not hardcoded in the gem; you can override it. The setter Phonelib.override_phone_data accepts a path to a Marshal.dump'ed file that merges with the built-in data. That is a real escape hatch for fixing a bad pattern without waiting for an upstream release. The gem also exposes add_additional_regex and additional_regexes to inject custom regex strings for specific country and type combinations.
Getting It Running: Installation and Core Configuration
Installation is a standard Gemfile line: gem 'phonelib', then bundle. After that you configure defaults in an initializer. The README gives a concrete example: Phonelib.default_country = "CN" or an array like ['CN', 'FR']. This default is what the parser falls back to when the number is not internationally unambiguous. Several toggles change parsing behavior. Phonelib.parse_special = true enables short codes and emergency numbers, which are off by default. Phonelib.vanity_conversion = true converts alphabetic characters to digits, so 800-CALL-NOW becomes 800-225-5669. Phonelib.strict_check = true disables sanitizing, meaning non-digit characters are not stripped and can cause a parse failure. You can also change the sanitize_regex to control which symbols are allowed. For formatting, extension_separator sets the output separator, defaulting to ';', and extension_separate_symbols defines what counts as an extension marker during parsing, either as a string of single characters or an array of strings like %w(ext # ; extension). These are all real keys, not abstractions.
ActiveRecord Validator: The Rails Integration
The gem's Rails integration is a validator that plugs into ActiveRecord models. The basic form is validates :attribute, phone: true, and the README notes that a blank value fails by default. That is a gotcha for forms where the field is optional; you need allow_blank: true to pass when empty. The validator accepts several options. possible: true switches from strict validation to a looser 'possible number' check, which is useful when a number is not fully valid but could be. types: [:voip, :mobile] restricts validation to specific number types, and countries: [:us, :ca] restricts by country. The country_specifier option takes a method name or a lambda, letting you supply a country per record, which is essential when you store national numbers without a country prefix. The extensions: false option enforces that no extension is present. These options give you fine control, but they also mean you need to read the docs to know what the default behavior is. The README shows a lambda example that calls .country on the record, which is a practical pattern for international apps.
A Real Limitation: It Is Not the Full Google Library
The README is honest: the gem does not include all of Google's functionality. That is the main limitation. If you need carrier lookup, timezone detection, or geolocation, Phonelib will not help. The gem also depends on the data version it ships. If libphonenumber updates a pattern for a country, Phonelib only gets it when the gem releases a new version. The README's advice to check the original libphonenumber demo and file issues with Google if parsing is wrong is a direct admission that the gem is a wrapper, not a source of truth. Another failure mode is the default strictness. With parse_special disabled, short codes and emergency numbers fail validation, which could be wrong for apps that need to accept them. Also, the default sanitization strips many symbols, so a user input like '+1 (555) 123-4567' is fine, but if you set strict_check to true, that same input might fail because the parentheses and spaces are not removed. That is a trade-off you must configure consciously.
Configuration Trade-offs: strict_check and ignore_plus
Two settings show how the gem balances permissiveness versus correctness. Phonelib.strict_check = true disables sanitizing, so the parser keeps only digits and the specified sanitize_regex symbols. This is useful when you want to reject inputs that contain unexpected characters, but it can also reject valid user input that includes spaces or dashes. Phonelib.ignore_plus = true changes how a leading '+' interacts with the default country. Normally, if the number starts with '+' and the country's prefix does not match, the gem resets the country. With ignore_plus, it keeps the default country even if the prefix does not match. That is a niche but important switch for apps that have a strong default country and want to parse numbers like '+44 20 7946 0958' as a UK number even when the default is US. The README also mentions strict_double_prefix_check, which controls whether a double prefix like '001' is sanitized. These toggles are not obvious from the gem's name, so a new user should read the configuration section carefully. Each one changes the outcome of validation, and the defaults are not always what a developer expects.
Alternatives and How They Differ
The obvious alternative is to use Google's libphonenumber directly, either through a Java or JavaScript binding, or through a Ruby port that is more complete. For Ruby, the closest comparison is the 'phony' gem, which also validates and formats phone numbers but uses its own data and logic rather than libphonenumber's. The difference is in the data source and update cycle. Phonelib inherits Google's battle-tested patterns, which are updated frequently by a large community. Phony maintains its own dataset, which may be smaller or less current. Another alternative is to call a remote API like Twilio Lookup or numverify, but that introduces network latency and a dependency on an external service. Phonelib is offline and fast, but it cannot be more accurate than its bundled data. If you need the absolute latest numbering plan changes, you would have to override the data or wait for a gem release. The README shows how to override with override_phone_data, which is a way to bridge that gap, but it requires you to maintain a Marshal.dump'ed file yourself.
Maintenance and Upgrade Cost
The gem is actively maintained, with releases in August 2026, and the repository is not archived. The release notes are on the GitHub releases page, which is the place to check for changes. The MIT license means you can use it in commercial projects without restriction, and you can modify the data or code as needed. The upgrade cost is low for standard use, but you should watch for changes in the data format or configuration defaults between releases. The README warns that the gem is based on libphonenumber, so when libphonenumber changes its data structure, Phonelib may need a major version bump. The override_phone_data feature is a double-edged sword: it lets you fix issues immediately, but your override file is your responsibility, and it can conflict with upstream updates. If you use the additional_regexes feature, those regexes are strings that you maintain in your codebase. That is a small but real maintenance burden. The gem's own documentation points you to Google's issue tracker for parsing problems, which means you should budget time to check upstream fixes rather than expecting the gem to solve everything.
Editorial conclusion
Adopt Phonelib if you need straightforward phone validation and formatting in a Ruby or Rails app and you accept that it does not implement every libphonenumber feature. Skip it if you require the full Google library, such as carrier or timezone lookup, or if you need to handle obscure numbering plans that the gem's data does not cover. Before adopting, verify that your target countries and number types pass both possible and strict checks, and test the specific parsing edge cases your users will hit. Confirm the gem's data freshness against the libphonenumber release cycle, since the gem is a wrapper and its accuracy depends on upstream data. The gem's own README tells you to report parsing mismatches to Google's issue tracker, which is a clear sign of where the boundary lies.
Frequently asked questions
Does the Phonelib gem call Google libphonenumber at runtime?
No. It bundles a copy of that library's metadata and states that all validations are based on it and that the gem's data is based on it. The gem also states that it does not include all of the library's functionality.
A phone number is parsed wrongly by Phonelib. What should I do?
Check the same number in Google's own browser demo for the library. If it parses the same way, the README says to open an issue with Google. If you cannot wait, add your own pattern with the additional-regex methods.
Can I replace the phone data Phonelib uses?
You can supply a marshalled file through the override setter, and the README says the gem does a merge between the two hashes, so entries can be added but not removed or replaced.
Does a blank phone field pass Phonelib validation by default?
No. The README notes that passing a blank value also fails, and lists an allow-blank option for callers who want an empty value to pass.
How do I set the default country in Phonelib?
Assign one country code as a string in an initializer, or assign an array of them to try several in order. The codes are the two-letter ISO country codes. The README also documents a validator option that resolves the country per record, which is what you want when numbers are stored without a country prefix.
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/daddyz-phonelib)Star history chart for your README
[](https://hysenlabs.com/projects/daddyz-phonelib)