If you've ever seeded a staging database with faker and then watched
your checkout form reject every single address, this post is for you.
The problem: three layers of address validation
Address fields in a modern US checkout or signup form typically pass
through three layers:
- Format checks — is the ZIP five digits, is the state a valid two-letter code? Any random data passes this.
-
Region-consistency checks — do the city, state and ZIP actually
belong together? USPS-style validators and services like Google
Address Validation all do this.
123 Main St, New York, CA 90001dies here: New York is not in California, and 90001 is Los Angeles. - Deliverability checks — does the house number exist? Only logistics flows go this deep; test environments almost never need it.
The catch: most fake-data libraries generate each field
independently. faker.location.city() and
faker.location.zipCode() don't know about each other, so nearly every
generated record fails layer 2 — and your tests fail for reasons that
have nothing to do with your code.
Fix 1: hand-curated matched sets
For a handful of records, just keep a small table of combinations that
belong together:
| City | State | ZIP | Area code |
|---|---|---|---|
| Portland | OR | 97205 | 503 |
| Austin | TX | 78701 | 512 |
| Denver | CO | 80202 | 303 |
Worth adding to any test suite as edge cases:
-
Two-word states —
Rhode Island,South Carolina: naive parsers split on spaces and readRhodeas a city. -
Washington, DC — not a state, but every form treats it as one.
Its addresses carry quadrant suffixes (
1600 K St NW≠1600 K St NE). -
Utah grid addresses —
455 S 300 Ehas no street name at all. Great for breaking address parsers that assumeName + St/Ave. - Tax-free states — OR, DE, MT, NH, AK have no statewide sales tax; pair them with a high-tax state like CA to test both checkout branches.
Fix 2: a dataset with the relationships baked in
I open-sourced the states/cities/ZIP building blocks I use (MIT):
us-address-sample-data
— 51 states with real area codes and tax flags, 255 cities where every
ZIP genuinely belongs to that city. Import the JSON and compose
addresses locally with zero dependencies.
Fix 3: an API that does it for you
For CI or quick scripts, I built a free endpoint (no key, CORS enabled,
up to 100 records per request):
bash
curl "https://addressmock.com/api/addresses?count=10&state=CA"
Copy
const res = await fetch(
"https://addressmock.com/api/addresses?count=20&type=us_tax_free"
);
const { results } = await res.json();
// every record: matched city/state/ZIP/area code + name, email, phone
Copy
Parameters: count (1–100), type (us / us_tax_free / hk / cv), state, city, gender. There's also a browser UI with batch generation and CSV/JSON export if you prefer clicking to curling.
The obligatory disclaimer
All of this produces format-correct samples, not verified deliverable addresses. It's for testing, demos and seeding — using fake addresses for real shipping, KYC or dodging region checks is a different thing entirely, and platforms are good at catching it.
What other locales or formats would be useful? I'm considering UK postcodes and Canadian postal codes next.
Top comments (0)