npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fakeaddresses

v0.2.0

Published

Typed client + CLI for the Fake Addresses API — postal-format-valid, non-deliverable US test addresses. Deterministic ?seed= + dataset, CC0 output, zero runtime dependencies.

Readme

fakeaddresses

Typed TypeScript client + CLI for the Fake Addresses API — a free, keyless API that generates postal-format-valid, non-deliverable US test addresses for QA and development.

  • Zero runtime dependencies. Wraps the platform fetch. Nothing to audit.
  • ?seed= + dataset determinism, built in. Same seed, same dataset version, same records — forever.
  • Every export format the API supports: JSON, NDJSON, CSV, SQL (7 dialects), XLSX — up to 10,000 rows per request, no account, no queue.
  • Free to use output. No attribution required, unlike Fake Name Generator, whose attribution clause blocks committing its fixtures into a public repository.
  • TypeScript types that match the real API, not an approximation of it (GeneratedRecord, AddressesResponse, MetaResponse, CoverageResponse — see src/types.ts).
  • Works from Node ≥18 or a browser via the CLI's underlying FakeAddressesClient, and via npx with no install step.

This package does not generate addresses locally and does not bundle any dataset — it calls the live API at https://fakeaddresses.com/api/v1 (or any base URL you point it at, e.g. a local dev server).

Install

npm install fakeaddresses

Or use the CLI without installing anything:

npx fakeaddresses generate --seed ci-fixture --state TX --count 5

Quick start — library

import { FakeAddressesClient } from 'fakeaddresses';

const client = new FakeAddressesClient();

const { records, dataset, generation } = await client.getAddresses({
  seed: 'ci-fixture',
  stateUsps: 'TX',
  count: 5,
});

console.log(records[0].lastLine); // "Austin, TX 78701"
console.log(dataset);             // "2026.09"
console.log(generation.poolSize); // distinct records this filter matches

Pin the seed once and get the identical five records back on every future call, from any machine, forever (as long as you also pin dataset):

await client.getAddresses({ seed: 'ci-fixture', dataset: '2026.09', stateUsps: 'TX', count: 5 });

Countries other than the United States

Pass country with an ISO 3166-1 alpha-2 code. The API serves 51 countries:

const { records } = await client.getAddresses({ seed: 'ci-fixture', country: 'DE', count: 5 });
console.log(records[0].addressLines); // ["Kastanienweg 17", "90402 Nürnberg"]

country replaces the US filters rather than combining with them — stateUsps, city and zip describe US localities, and the server rejects them alongside country instead of ignoring them, so a typo cannot quietly return a different country's data. Omit country for the United States.

client.getCoverage() lists every served country with the coherence level it guarantees, which is what decides whether a country suits a given test:

| level | what is guaranteed | |---|---| | full | the county and time zone are derived from the record's own point | | admin-area | the administrative area is real and contains the point | | format-only | the postal format is correct for that country |

A pinned dataset works for a country too: an older version is served from its own published bytes, so a committed seed keeps returning the same records. A version that publishes no corpus for the country you asked for is refused with a 400 naming the one that does, rather than quietly substituted.

Omit seed to get fresh, randomly-chosen output — the response always echoes the seed it used (seedWasGenerated: true), so you can pin it afterwards once you've found a record set you want to keep.

Quick start — CLI

# One address, printed as JSON
npx fakeaddresses generate

# Five deterministic Texas addresses
npx fakeaddresses generate --seed ci-fixture --state TX --count 5

# 5,000-row CSV fixture, written to a file
npx fakeaddresses generate --seed ci-fixture --state TX --count 5000 --format csv --out fixtures/addresses.csv

# A ready-to-run seed file for MySQL
npx fakeaddresses generate --format sql --sql-dialect mysql --table qa_addresses --count 500 --out seed.sql

# Service metadata: current rate limit, dataset versions, export formats
npx fakeaddresses meta

# Which US states/counties the published dataset currently covers
npx fakeaddresses coverage

Run npx fakeaddresses help for the full flag reference. Every generate flag maps 1:1 onto a query parameter of GET /api/v1/addresses — see the OpenAPI spec for the authoritative parameter list.

Export formats

exportAddresses covers every non-JSON format the API serves. It buffers the full response (the API caps every request at 10,000 rows, so this is bounded) and returns the raw bytes plus the metadata the API carries in headers for these formats, since there is no JSON envelope to put it in:

import { writeFileSync } from 'node:fs';
import { FakeAddressesClient } from 'fakeaddresses';

const client = new FakeAddressesClient();

const csv = await client.exportAddresses({ seed: 'ci-fixture', stateUsps: 'TX', count: 1000, format: 'csv' });
writeFileSync(csv.filename ?? 'addresses.csv', csv.data);

const sql = await client.exportAddresses({
  seed: 'ci-fixture',
  stateUsps: 'TX',
  count: 500,
  format: 'sql',
  sqlDialect: 'postgres',
  table: 'qa_addresses',
});
writeFileSync('seed.sql', sql.data);

Supported format values: json (via getAddresses), ndjson, csv, sql, xlsx (via exportAddresses). Supported sqlDialect values: postgres, mysql, sqlite, mssql, oracle, bigquery, snowflake.

The determinism contract

This is the thing no other web address generator publishes as a contract rather than an accident: the same seed plus the same dataset version returns byte-identical records, forever, across deploys. Concretely:

  • ?seed= selects a deterministic permutation of the records matching your filter — drawn without replacement, so a 10,000-row export never contains a duplicate address unless the filter's pool is genuinely smaller than what you asked for (reported honestly via generation.poolExhausted, never hidden).
  • index (0-based) lets you page through a pinned seed's sequence: index=5&count=1 is always exactly what you'd get by reading position 5 of a count=6 read of the same seed.
  • A response is pinned to a dataset version, and the version is named in the response rather than here, because a version written into a README goes stale at the next release. Old versions stay addressable for at least 12 months once a newer one ships (GET /api/v1/meta → dataset.known lists what a given deployment still serves) — a pinned seed's output cannot silently drift because the underlying data refreshed.

This makes the API usable as a CI fixture source: commit the seed (and, if you care about long-term reproducibility, the dataset version) instead of committing the data.

Honest coverage

The published dataset is US only and is not nationwide — it says so in its own GET /api/v1/coverage response rather than implying otherwise. The exact counts are deliberately not printed here: they change with every dataset release, and a number in a README is a number nobody re-measures. client.getCoverage() returns the live figures. What does not change between releases:

  • Coverage is a subset of US ZIP Code Tabulation Areas (ZCTAs) and counties, never the whole country, and the response states both the covered count and the national total so you can see the fraction rather than infer it
  • Area codes at state precision — an emitted NPA is valid for the record's state, not guaranteed valid for its specific county or rate centre, because no free source maps numbering ranges to counties with the precision that claim would need
  • Mailing city currently resolves via a place-boundary fallback for records where a direct USPS ZIP→city source isn't yet wired in — those records carry coherenceClaimExcluded: true and city.source: "place_boundary" so you can filter them out if your test needs the USPS last-line city specifically

Call client.getCoverage() before picking a stateUsps/city/zip filter if you need to know ahead of time whether it's covered — a filter with no coverage returns an honest 422 (via FakeAddressesApiError) rather than an invented address or a silent empty result.

Unknown parameters are rejected, not ignored. Passing something the endpoint does not understand returns a 400 naming it, rather than quietly dropping it and returning data that looks like it matched. A mistyped stat=TX therefore fails loudly instead of handing back unfiltered national records, and country returns a 400 explaining that this endpoint serves US records only — answering a request for another country with a US address would be worse than refusing it.

On deliverability: every record's street number is drawn from outside every address range the street and boundary reference data publishes for that street segment, on both sides, parity-matched. That is not the same as a registered delivery-point file — no public one exists — record.nonDeliverable.byConstruction is always true, and record.nonDeliverable.method says how. This is a structural guarantee about how the data is generated, not a result from running records through USPS Delivery Point Validation — no DPV sample against this dataset has been published yet, so this README makes no claim about a measured DPV pass/fail rate.

Safe-by-construction opt-in fields

includeEmail, includeSsn and includeCreditCard are opt-in and, when present, are never a value that could belong to a real person or fire a real system:

  • Email — always an RFC 2606 reserved domain (example.com/.org/.net/.invalid).
  • SSN — always area 000 or 666, group 00 (e.g. 666-00-4821) — invalid on two counts, and never in the 9xx range the IRS actually issues real ITINs/ATINs in.
  • Credit card — always a processor-published sandbox PAN (e.g. Stripe's 4242424242424242), labelled "publisher test value". Never an arbitrary Luhn-valid number, which can collide with a real card.
  • Phone — always 555-0100–555-0199, the range the North American Numbering Plan reserves for fiction.

Rate limit

The API is free and keyless. The published anonymous limit is 60 requests per minute per client, enforced server-side and echoed on every response via both the legacy X-RateLimit-* headers and the standards-track RateLimit-* form (draft-ietf-httpapi-ratelimit-headers). client.exportAddresses(...).rateLimit surfaces the parsed values; a 429 throws FakeAddressesApiError with status: 429. Call client.getMeta() for the current published number rather than hardcoding it — this README states it, but the API response is the source of truth.

Output licence

Every record's own licence field (and the X-Licence/X-Licence-Url response headers) confirms it: API output is free to use, with no rights reserved. No attribution required — commit generated fixtures straight into a public repository.

Error handling

import { FakeAddressesApiError } from 'fakeaddresses';

try {
  await client.getAddresses({ zip: '00000' });
} catch (error) {
  if (error instanceof FakeAddressesApiError) {
    console.error(error.status, error.code, error.message);
    if (error.status === 422) console.error(error.coverageHint);
  }
  throw error;
}

Local development against this repo

If you're working against a local checkout of the site (npm run build && npm run start), point the client or CLI at it instead of production:

const client = new FakeAddressesClient({ baseUrl: 'http://localhost:3000/api/v1' });
npx fakeaddresses generate --base-url http://localhost:3000/api/v1 --seed ci-fixture --count 5

API reference

The full contract — every parameter, every response shape, every error code — is the published OpenAPI 3.1 spec. This package's src/types.ts mirrors it directly; client.ts is a thin fetch wrapper with no logic of its own beyond building the query string and parsing the response.

| Method | API route | Returns | |---|---|---| | client.getAddresses(params?) | GET /api/v1/addresses (format=json) | AddressesResponse | | client.exportAddresses(params) | GET /api/v1/addresses (format ∈ ndjson|csv|sql|xlsx) | ExportResult (raw bytes + header metadata) | | client.getMeta() | GET /api/v1/meta | MetaResponse | | client.getCoverage() | GET /api/v1/coverage | CoverageResponse |

Testing

This package's own test suite mocks fetch and runs with no network access:

npm test

Why this exists

At least three public repositories exist purely to scrape a competing address generator because it has no API at all. This package exists so nobody needs to write a fourth: the underlying API is free, keyless, documented with a real OpenAPI spec, and this package is a thin, typed, zero-dependency wrapper over it.

Changelog

0.1.1 — fixes the ESM entry point. 0.1.0 shipped dist/esm/ with extensionless relative imports (export ... from './client') under "type": "module", which Node's ESM resolver rejects, so import 'fakeaddresses' threw ERR_MODULE_NOT_FOUND. require() was unaffected. If you installed 0.1.0 and use ESM, upgrade. The package now has tests that load the built dist/ the way a consumer does, rather than only testing src/, which is why the defect reached the registry at all.

0.1.0 — first release. Use 0.1.1 instead if you import via ESM.

Source

The source for this package is private at this time. The published tarball contains the compiled client, its type declarations and the CLI, and nothing else; there is no public repository to link to yet. That is a deliberate decision by the project owner rather than an oversight, and it is the one thing this README cannot give you that a reader might reasonably expect.

What it means in practice: you can read every line that ships by unpacking the tarball (npm pack fakeaddresses && tar -xzf fakeaddresses-*.tgz), the package has no dependencies to audit, and it talks to exactly one documented HTTP API that you can call yourself without it. If the repository is opened later this section will say so.

Licence

MIT for this package's code (see LICENSE). API output is free to use, with no attribution required — see "Output licence" above.