One identity, two displays

Our fixed US fixture formats as +1 202 555 0123 internationally and (202) 555-0123 nationally. Our GB fixture formats as +44 7700 900123 internationally and 07700 900123 nationally. These measured strings come from libphonenumber-js/max version 1.13.15, not a hand-written punctuation rule. Their stored identities are +12025550123 and +447700900123.

The library's parsing documentation assigns defaultCountry to non-international input. Explicit plus-prefixed international input uses its own calling code. We set extract: false so the experiment parses the whole field instead of finding a number inside surrounding prose.

const original = parsePhoneNumberWithError(fixture.e164, { extract: false });
const display = original.formatNational();
const reparsed = parsePhoneNumberWithError(display, {
  defaultCountry: fixture.region,
  extract: false
});
assert.equal(reparsed.number, fixture.e164);

The contract is parse(format(canonical), context).number === canonical. Formatting may choose new punctuation; it need not reproduce the user's original text. Keep that raw input separately if the product needs an audit or exact visual replay.

Our measured matrix: 11 identity checks and 6 negative controls

We ran 17 case assertions on October 12, 2026, on Node v24.19.0. All 17 matched their stated expectations: 11 preserved canonical identity, and 6 deliberately lost context or serialized the wrong value. A passing negative assertion means the experiment detected a mismatch; it does not mean that input is safe to accept.

CaseDisplay inputParsing contextMeasured outcome
US-international-no-context+1 202 555 0123NoneSame canonical
US-international-wrong-default+1 202 555 0123GBSame canonical
US-national-correct-context(202) 555-0123USSame canonical
US-national-extra-spaces(202) 555-0123USSame canonical
US-second-display-roundtrip+1 202 555 0123NoneSame canonical
US-national-missing-context(202) 555-0123NoneINVALID_COUNTRY
US-national-wrong-context(202) 555-0123GBDifferent value
GB-international-no-context+44 7700 900123NoneSame canonical
GB-international-wrong-default+44 7700 900123USSame canonical
GB-national-correct-context07700 900123GBSame canonical
GB-national-extra-spaces07700 900123GBSame canonical
GB-second-display-roundtrip+44 7700 900123NoneSame canonical
GB-national-missing-context07700 900123NoneINVALID_COUNTRY
GB-national-wrong-context07700 900123USDifferent value
GB-00-prefix-with-GB-origin00447700900123GBSame canonical
GB-00-prefix-with-US-origin00447700900123USDifferent value
GB-naive-country-plus-national-digits07700 900123NoneDifferent value

For both fixtures, international display survived absent and deliberately wrong default-country values. National display survived correct context and extra ASCII spaces. A second display/parse cycle retained the canonical string and both normalized display forms. Without country context, both national inputs threw INVALID_COUNTRY. With the other country's context, they parsed to a different canonical value rather than necessarily throwing. Therefore, successful parsing alone does not satisfy this fixture's identity assertion.

This is a small deterministic matrix for complete US/GB inputs, not a random property-testing campaign, all-country guarantee, phone allocation check or execution of our production formatter. Our normalization cases explain one-way transformations; this downloadable experiment checks the separate return trip from display to stored identity.

The domestic zero belongs to a specific numbering plan

In the GB case, the national display begins with 0, while the parsed national significant number does not. The deliberately weak serializer '+44' + national.replace(/\D/g, '') keeps that domestic zero and fails raw equality with the fixture's canonical value. We compare the serialized text before parsing it: a forgiving parser might repair the string and conceal the broken serializer contract.

Google's libphonenumber FAQ explains country-dependent prefix handling, including exceptions where leading zeros remain significant. Our GB result is not a rule to strip every country's leading zero. Let the selected parser and its pinned metadata interpret the known context.

The same GB fixture written with 00 instead of + returned the expected identity under GB origin context, but a different value under US context. The FAQ documents that international dialing prefixes depend on the origin region. Do not globally replace 00 with + just because one fixture round trip worked.

Parsing, validity and deliverability have different jobs

For this package's max metadata, the US fixture reports isPossible() === true and isValid() === true. The GB fictional mobile reports isPossible() === true and isValid() === false, while all its intended format/parse identity cases still pass. We record validity separately; we do not use it as the oracle for a formatting fixture.

The examples were checked against our source-pinned dataset. The US value is in NANPA's limited fictional 555-0100 through 555-0199 interval. The GB value is in Ofcom's drama mobile range. Both fixture records explicitly retain fictionalOnly: true and deliveryAllowed: false. Unexpected parsed strings in negative controls are error evidence, never new fixtures to call or text.

Reproduce the exact package and metadata

Download these four files into the same directory: experiment.mjs, package.json, package-lock.json, and the measured results.json. Dependency installation uses the package registry; the experiment itself has no network or messaging client.

npm ci --ignore-scripts --no-audit --no-fund
node experiment.mjs

Package version: 1.13.15. Entry point: libphonenumber-js/max. SHA-256 of the installed metadata.max.json: 197aabc11a950b88234f2eb20b8259cffa09e975b3ebe90bdd10badefd91dee4. Metadata schema version 4 describes the file format; it is not an update date. Record the file hash as well as the package version.

On a dependency update, rerun the same fixture identities and compare displays, canonical results and diagnostic flags separately. Review an intentional display change without silently rewriting the canonical value. Expand the matrix using documented fictional examples for each additional country; never infer complete coverage from these two fixtures.

Questions from the display boundary

A public English developer question describes inconsistent imported formats and missing country information. It is one question signal, not a count of affected users or a source for numbering rules. The matrix above supplies our own measured answers.

Can a phone number generator's national display be parsed without country context?

Do not assume it can. Both national displays in our experiment failed without context. Preserve the fixture's country or retain explicit international input.

Does a successful parse prove the round trip kept the same number?

No. Both wrong-country national inputs parsed but changed the canonical value. Compare the result with the original fixture identity.

Should I remove every leading zero before adding a country code?

No. Prefix handling depends on the numbering plan. Our GB domestic zero is removed by a country-aware parser; that outcome is not universal.

Must a fictional formatting fixture pass isValid()?

No. Our GB example round-trips while reporting false for validity. Record the structural result separately and keep delivery disabled.

Does round-trip equality preserve the original spaces and punctuation?

No. It checks canonical identity. Normalized display stability is a separate assertion; exact user text needs its own stored field.

Original material: 17 measured assertions, a two-fixture context-loss matrix, a deliberately weak serializer control, metadata fingerprint, reproducible source and an original diagram. Offline fictional data only; no calls or SMS.