Open Source

zipcode-detail-lookup

Zero-dependency Node.js package for US zip code lookup — city, state, county, timezone, lat/lng for 33,000+ zip codes. No API key. Works offline. Perfect for test data generation and address validation.
TypeScriptZero dependencies33,000+ US zip codesLat, lng & timezone
zipcode-detail-lookup-example.ts
import { lookupZip, randomZip, lookupZipsWith } from 'zipcode-detail-lookup';

// Look up a specific zip code
const fll = lookupZip('33316');
fll.city;   // Fort Lauderdale
fll.stateName;  // Florida
fll.county; // Broward

// Generate random valid zip code for test data
const zipData = randomZip();

// Search by criteria
const results = lookupZipsWith({
  stateAbbreviation: 'FL',
  population: 27000,
  populationOperator: '>'
});

What is zipcode-detail-lookup?

zipcode-detail-lookup is a zero-dependency Node.js package that resolves a US zip code into a full set of geographic and demographic data — city, state, county, latitude, longitude, timezone, population, and more. 33,000+ zip codes are bundled directly in the package, so lookups are instant with no network requests and no API keys required.

It serves two audiences well:

  • Test automation engineers who need realistic, valid US address data for automated tests — without hardcoding fake values that break against real validation logic
  • Node.js developers building features that involve zip code lookup, distance calculation, or location-based filtering
  • Anyone who doesn't want the overhead or security concerns of an external API — no keys, no outbound network calls, no rate limits.

I built it to solve a specific problem in my own test automation work where I needed to generate unique, realistic US addresses where the zip code, city, state, and county formed a valid combination — addresses that would pass real address form validation, not just look plausible. Most of the existing solutions required a service call or API key, which limited where my tests could run. My solution turned out to be broadly useful enough to package and share. If you're running into the same challenge, this package is for you.


Generating Valid Test Data with Real Zip Codes

I was testing a web application where an intermediate screen required a unique address on every test run — and I couldn't tear down user data between runs. The easy solution — just make up a random state, zip, and county — didn't hold up because the address form validated that all three had to form a real, consistent postal combination. Random uncorrelated values would fail validation every time.

randomZip() solves this by returning a different, fully valid zip code on every call. Every field it returns — city, state, county, zip — is a real, internally consistent location:

address-test-data.ts
import { randomZip } from 'zipcode-detail-lookup';

const localityData = randomZip();

// All fields are real and consistent with each other
console.log(localityData.zip);   // e.g. 94103
console.log(localityData.city);  // e.g. San Francisco
console.log(localityData.stateName); // e.g. California
console.log(localityData.county); // e.g. San Francisco

When your test scenario requires address data that meets specific criteria — a particular state, a minimum population threshold, or a non-military zip — lookupZipsWith lets you filter the dataset and pick from the results:

filtered-test-data.ts
import { lookupZipsWith } from 'zipcode-detail-lookup';

// Generate a valid California address for a state-specific validation test
const californiaZips = lookupZipsWith({ stateAbbreviation: 'CA' });
const testAddress = californiaZips[Math.floor(Math.random() * californiaZips.length)];

// Need a zip from a populated area to avoid edge cases?
const populatedZips = lookupZipsWith({
  stateAbbreviation: 'TX',
  population: 10000,
  populationOperator: '>',
});

This approach gives your test suite variety across runs without any maintenance overhead.


Zip Code Lookup and Distance Calculation in Node.js

Beyond test data, the zipcode-detail-lookup Node.js package is useful anywhere your application works with US locations. Common use cases include enriching user-submitted zip codes with city and state for display, validating that a zip code actually exists before processing a form, filtering records by state or county, and calculating straight-line distances between two locations.

The distanceBetweenZips function uses each zip code's latitude and longitude with a Haversine formula to calculate the approximate real-world distance between two points on Earth's surface:

distance.ts
import { distanceBetweenZips } from 'zipcode-detail-lookup';

// Distance in miles
const miles = distanceBetweenZips('10001', '90001', true);
console.log(miles); // 2448.35 — New York to Los Angeles

// Distance in kilometers
const km = distanceBetweenZips('10001', '90001', false);
console.log(km); // 3940.24

Since all data is local to the package, distance calculations run synchronously with no latency — useful for sorting search results by proximity or enforcing delivery radius rules without hitting an external geocoding API.


Installation

Terminal
npm install zipcode-detail-lookup --save
import-snippet.ts
import {
  lookupZip,
  lookupZipsWith,
  randomZip,
  distanceBetweenZips,
} from 'zipcode-detail-lookup';

API

lookupZip

Look up a specific zip code and get back a full details object. Returns null if the zip code is not found:

lookupZip.ts
const fll = lookupZip('33316');

console.log(fll?.city);              // Fort Lauderdale
console.log(fll?.stateName);         // Florida
console.log(fll?.stateAbbreviation); // FL
console.log(fll?.county);            // Broward
console.log(fll?.timezone);          // America/New_York

// Always guard against null for unrecognized zip codes
const result = lookupZip('00000');
if (result === null) {
  console.log('Zip code not found');
}

randomZip

Returns a random zip code from the dataset with all associated properties. Unlike lookupZip, randomZip always returns a valid ZipCode — it never returns null. Useful for generating varied, realistic US addresses for test data without hardcoding values:

randomZip.ts
const rZip = randomZip();

console.log(rZip.zip);   // e.g. 94103
console.log(rZip.city);  // e.g. San Francisco
console.log(rZip.stateName); // e.g. California

lookupZipsWith

Search for zip codes matching any combination of criteria. Returns an array of matching ZipCode objects, or an empty array if no zip codes match — it never returns null:

lookupZipsWith.ts
// Find all zip codes in Florida with population greater than 27,000
const results = lookupZipsWith({
  stateAbbreviation: 'FL',
  population: 27000,
  populationOperator: '>',
});

The full set of search parameters:

ISearchParams.ts
interface ISearchParams {
  city?: string;
  county?: string;
  stateName?: string;
  stateAbbreviation?: string;
  militaryZip?: boolean;
  population?: number;
  populationOperator?: '<' | '>' | '=';
}

distanceBetweenZips

Calculates the direct distance between two zip codes using their latitude and longitude, accounting for the approximate curvature of the Earth. Returns null if either zip code is not found:

distanceBetweenZips.ts
const distanceInMiles = distanceBetweenZips('10001', '90001', true);
// --> 2448.35 miles (New York to Los Angeles)

const distanceInKilometers = distanceBetweenZips('10001', '90001', false);
// --> 3940.24 kilometers

// Returns null if either zip is unrecognized
const invalid = distanceBetweenZips('00000', '90001', true);
// --> null

Available Properties

Every result object returned by lookupZip, randomZip, and lookupZipsWith exposes the following properties:

PropertyTypeDescription
zipstringThe zip code
citystringCity name
stateNamestringFull state name
stateAbbreviationstringTwo-letter state abbreviation
countystringCounty name
latitudenumberLatitude coordinate
longitudenumberLongitude coordinate
populationnumber | nullPopulation count
densitynumber | nullPopulation density
timezonestringIANA timezone string
militaryZipbooleanWhether this is a military zip code
zctabooleanZIP Code Tabulation Area designation
imprecisebooleanWhether the location data is approximate
county_fipsnumberFIPS county code

The package ships full TypeScript definitions. Return types are:

FunctionReturn type
lookupZipZipCode | null
randomZipZipCode
lookupZipsWithZipCode[]
distanceBetweenZipsnumber | null

Frequently Asked Questions

Changelog

1.1.8 — Typo Fix and Dependency Security Update

Documentation typo fix npm audit security update to underlying dependency

1.1.7 — Dependency Security Updates

Security updates to underlying dependencies.

1.1.4 — Distance Calculation

Added distanceBetweenZips — calculate the distance between two zip codes in miles or kilometers using latitude and longitude with Earth curvature correction.

1.1.2 — Removed Lodash

Removed Lodash dependency for a leaner install footprint.

1.1.1 — Performance Improvements

Improved lookup speed.

1.1.0 — API Rename

Functions renamed for a cleaner, more consistent API.

1.0.0 — Initial Release

Initial release with lookupZip, randomZip, and lookupZipsWith.

Ready to use zipcode-detail-lookup?

Zero dependencies, no API keys, works in any Node.js project.

npm install zipcode-detail-lookup