Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 3 min read

Why "1 city = 1 area code" breaks local phone number matching (and how to model overlays in JavaScript)

A common mistake in CRM routing and voice applications is checking whether two phone numbers belong to the same metro area by comparing their first three digits (npaA === npaB). That worked before the mid-1990s, when st

A common mistake in CRM routing and voice applications is checking whether two phone numbers belong to the same metro area by comparing their first three digits (npaA === npaB).

That worked before the mid-1990s, when state utility commissions relieved exhausted area codes through geographic splitsβ€”drawing a boundary line on a map and forcing everyone on one side to change their phone number. Under 47 CFR 52.19, commissions shifted almost entirely to all-services distributed overlays: adding a new area code to the exact same geographic footprint so existing subscribers keep their numbers and everyone dials 10 digits.

As a result, neighbors on the same streetβ€”or two phone lines in the same officeβ€”routinely have different area codes.

How overlays stack up in fast-growing metros

Look at seven major Texas and Southwest metros from NANPA's active area code records:

  • Houston (713 area code guide): Five area codes cover the same Houston territoryβ€”713 (1947), 281 (split in 1996, re-merged into a full overlay in 1999), 832 (1999), 346 (2014), and 621 (2025).
  • Dallas (214 area code guide): Four codes share the Dallas metroβ€”214 (1947), 972, 469, and 945.
  • Fort Worth (817 area code guide): Shares the Fort Worth region (817, created in 1953) with overlay 682.
  • Austin (512 area code guide): Original 1947 code 512 shares Central Texas with overlay 737.
  • San Antonio (210 area code guide): Split from 512 in 1992 and now shares Bexar County with overlay 726.
  • Phoenix (602 area code guide): Split into 602, 480, and 623 in 1999, then combined in 2023 by eliminating the internal boundaries so all three codes overlay the entire metro.
  • Las Vegas (702 area code guide): Original 1947 code 702 shares Clark County with overlay 725 (added in 2014).

Normalizing area codes to their overlay group

Instead of comparing raw 3-digit strings, map every area code in an overlay complex to a canonical metro cluster:

const OVERLAY_GROUPS = [
  { metro: "Houston, TX",     primary: "713", codes: ["713", "281", "832", "346", "621"] },
  { metro: "Dallas, TX",      primary: "214", codes: ["214", "972", "469", "945"] },
  { metro: "Fort Worth, TX",  primary: "817", codes: ["817", "682"] },
  { metro: "Austin, TX",      primary: "512", codes: ["512", "737"] },
  { metro: "San Antonio, TX", primary: "210", codes: ["210", "726"] },
  { metro: "Phoenix, AZ",     primary: "602", codes: ["602", "480", "623"] },
  { metro: "Las Vegas, NV",   primary: "702", codes: ["702", "725"] },
];

const codeToMetro = new Map();
for (const group of OVERLAY_GROUPS) {
  for (const code of group.codes) {
    codeToMetro.set(code, group);
  }
}

function extractNpa(phone) {
  const digits = String(phone).replace(/\D/g, "");
  const ten = digits.length === 11 && digits.startsWith("1") ? digits.slice(1) : digits;
  return ten.slice(0, 3);
}

function sameLocalMarket(numA, numB) {
  const npaA = extractNpa(numA);
  const npaB = extractNpa(numB);
  if (npaA === npaB) {
    return { sameMarket: true, metro: codeToMetro.get(npaA)?.metro ?? `NPA ${npaA}` };
  }
  const gA = codeToMetro.get(npaA);
  const gB = codeToMetro.get(npaB);
  if (gA && gB && gA.primary === gB.primary) {
    return {
      sameMarket: true,
      metro: gA.metro,
      primary: gA.primary,
      sharedCodes: gA.codes.length,
    };
  }
  return {
    sameMarket: false,
    metroA: gA?.metro ?? npaA,
    metroB: gB?.metro ?? npaB,
  };
}

Running the comparison

console.log(sameLocalMarket("713-200-1000", "621-200-1000"));
console.log(sameLocalMarket("214-200-1000", "945-200-1000"));
console.log(sameLocalMarket("214-200-1000", "817-200-1000"));
console.log(sameLocalMarket("602-200-1000", "480-200-1000"));

Output:

Pair npaA === npaB sameLocalMarket(a, b) Why
713 vs 621 false true (Houston, TX, 5 shared codes) 621 is the 2025 overlay on the 713/281/832/346 footprint
214 vs 945 false true (Dallas, TX, 4 shared codes) 945 is the 2021 overlay on 214/972/469
214 vs 817 false false (Dallas, TX vs Fort Worth, TX) Adjacent DFW numbering plan areas, separate overlay pools
602 vs 480 false true (Phoenix, AZ, 3 shared codes) Former split boundaries were merged into a single overlay in 2023

Practical takeaways for number provisioning

  1. Don't hardcode a single area code per city. If a customer asks for a "Houston local number" and 713 inventory is tight, 281, 832, 346, and 621 cover the exact same rate centers.
  2. Watch for boundary eliminations. Metros like Phoenix (602/480/623) and Houston (713/281) started as geographic splits and later converted into unified overlays when one side ran low on numbers.
  3. Keep an updated overlay table. You can check current overlay groups for every state on EaseDial's full U.S. area code list or browse individual city histories in the U.S. area code lookup directory.

Disclosure: I work with the team at EaseDial, which publishes the area code guides linked above.

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.