Skip to content

exeebit/anyaddress

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

anyaddress

Parse and normalize international street addresses in pure JavaScript. Zero dependencies, fully typed, and runs anywhere — Node.js, the browser, and edge/serverless runtimes (Vercel, Cloudflare Workers, Deno, Bun).

npm version npm downloads bundle size license

import { parseAddress } from "anyaddress";

parseAddress("123 Main St, Springfield, IL 62704");
// {
//   line1: "123 Main St",
//   city: "Springfield",
//   region: "IL",
//   regionName: "Illinois",
//   postalCode: "62704",
//   country: "US",
//   confidence: 0.95
// }

Why anyaddress?

Parsing a free-text address into structured fields in JavaScript is surprisingly painful:

  • The accurate option, libpostal, is a C library. Its Node binding (node-postal) needs a compiler and downloads ~2 GB of ML models — so it won't run on serverless or edge, and it's a nightmare to install in CI.
  • The pure-JS options are stale or US-only. The most popular (parse-address) hasn't shipped since 2019 and only handles US addresses.

anyaddress fills the gap: a maintained, pure-JavaScript, no-native-build address parser that handles the common US / Canada / UK / Australia formats — the bulk of real e-commerce and shipping traffic — and degrades gracefully for everything else.

Features

  • 🌍 International — US, CA, GB, AU out of the box, with a sensible generic fallback.
  • 📦 Zero dependencies — tiny, tree-shakeable, no native build step.
  • Runs anywhere — Node, browser, edge, serverless. Pure ESM + CJS.
  • 🔤 Normalization — standardize casing, street suffixes (Street → St), and region/postal codes.
  • 🧭 Country & postal-code detection from the address shape.
  • 🧱 Typed — first-class TypeScript types, never throws on junk input.

Install

npm install anyaddress

Usage

Parse

import { parseAddress } from "anyaddress";

parseAddress("100 Queen St W, Toronto, ON M5H 2N2");
// { line1: "100 Queen St W", city: "Toronto", region: "ON",
//   regionName: "Ontario", postalCode: "M5H 2N2", country: "CA", confidence: 0.95 }

parseAddress("12 Oxford Street, London, W1D 1BS");
// { line1: "12 Oxford Street", city: "London",
//   postalCode: "W1D 1BS", country: "GB", confidence: 0.8 }

Normalize

import { normalizeAddress } from "anyaddress";

normalizeAddress("123 main street, springfield, il 62704");
// "123 Main St, Springfield, IL 62704, US"

Detect country

import { detectCountry } from "anyaddress";

detectCountry("90210");        // "US"
detectCountry("K1A 0B1");      // "CA"
detectCountry("United Kingdom"); // "GB"

Force or fall back to a country

parseAddress("4 Privet Drive, Little Whinging", { defaultCountry: "GB" });
parseAddress("...", { country: "US" }); // skip detection

API

Function Returns Description
parseAddress(input, options?) ParsedAddress Parse free text into structured fields. Never throws.
normalizeAddress(input, options?) string Parse + standardize casing/suffixes into one clean line.
detectCountry(input) CountryCode | undefined Best-effort country from name or postal shape.
formatAddress(parsed) string Render a ParsedAddress back to a single line.
interface ParsedAddress {
  raw: string;
  line1?: string;       // street number + name
  line2?: string;       // unit / apt / suite
  city?: string;
  region?: string;      // state/province code when recognized
  regionName?: string;  // full state/province name
  postalCode?: string;
  country?: string;     // "US" | "CA" | "GB" | "AU" | ...
  confidence: number;   // 0–1
}

Comparison

anyaddress parse-address node-postal (libpostal)
Pure JS, no native build ❌ (C library)
Runs on edge / serverless
International ✅ (US/CA/GB/AU) ❌ (US only) ✅ (everywhere)
Maintained ❌ (2019)
Install size tiny tiny ~2 GB models
Accuracy on messy input good ok best

Limitations (honest)

This is a pragmatic, rules-based parser, not a statistical NLP model. For the highest accuracy on arbitrary, messy, worldwide input, libpostal is still the gold standard. anyaddress targets the 80–90% common-format case with zero install pain — perfect for checkout forms, shipping, CRM dedupe, and edge functions. PRs to widen country coverage are very welcome.

Contributing

Issues and PRs welcome — especially new country formats and test cases. Run npm test (Vitest) before submitting.

License

MIT © s4gor

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors