How Mailwoman compares
If you're geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. addresses, you've already met the trade-off. The hosted APIs (Google, Mapbox, OpenCage) are easy to start with and bill you forever, with a key you have to guard and a rate limit you have to design around. The self-hosted stacks (Nominatim, Photon, Pelias) are free, but they ask you to run PostgreSQL or Elasticsearch and feed it the planet before you can resolve a single address.
Mailwoman is the calibrated neural parser plus a geocoder that runs from a SQLite file — and, when you want them, the same drop-in HTTP APIs those tools expose, so you can repoint an existing client and keep going. The two rows that matter most are the ones a hosted service can never check:
- No API key required.
- No monthly fee.
Capability matrix
| Capability | Mailwoman | Nominatim | Photon | OpenCage | PeliasPeliasAn open-source geocoder, Mailwoman's spiritual predecessor. | libpostallibpostalAn open-source C address parser used by Pelias. Mailwoman's rule-based v0 and neural classifier supersede it. | Google / Mapbox |
|---|---|---|---|---|---|---|---|
| No API key required | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| No monthly fee (self-host free) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Open source | ✅ AGPL | ✅ | ✅ | ❌ | ✅ | ✅ MIT | ❌ |
| No Elasticsearch / no PostgreSQL import | ✅ SQLite | ❌ | ❌ | n/a | ❌ | ✅ | n/a |
| Runs in the browser (WASM) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Forward geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Reverse geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Autocomplete / type-ahead | ✅ | ➖ | ✅ | ➖ | ✅ | ❌ | ✅ |
| Structured address parsingaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. | ✅ neural | ➖ | ❌ | ➖ | ✅ | ✅ | ➖ |
| Annotations (timezone, UN/LOCODE, coordinate formats, flag, …) | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ➖ |
| Calibrated, routable confidence | ✅ | ❌ | ❌ | ➖ | ➖ | ❌ | ➖ |
| Drop-in compatible API | ✅ Nominatim · Photon · libpostallibpostalAn open-source C address parser used by Pelias. Mailwoman's rule-based v0 and neural classifier supersede it. | — | — | — | — | — | — |
✅ supported · ➖ partial · ❌ not supported · n/a not applicable (hosted-only)
What that buys you
You can run the whole thing on one box, ship it inside your application, or compile it to WebAssembly and geocode in the browser. You get forward and reverse geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available., autocomplete, and structured parsingaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. from the same modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' — and the OpenCage-style annotations block (timezone, coordinate formats, calling code, flag, and more) attached to every result, which the other self-hosted stacks don't return at all.
And when you're migrating from Nominatim, Photon, or libpostal, you don't rewrite your client. Point it at the matching package:
npx @mailwoman/nominatim serve # Nominatim-compatible /search, /reverse, /lookup, /status
npx @mailwoman/photon serve # Photon-compatible /api, /reverse (GeoJSON)
npx @mailwoman/libpostal serve # libpostal-compatible /parse, /expand
Where each tool still does something better, the switching guides say so plainly. The goal is to let you keep your stack, your client, and your budget, not to claim Mailwoman wins every row.
What about the map apps?
Some of the projects you'll meet in this space aren't geocoders at all. Cartes is a good example: an open-source web map for the general public, built in France on OpenStreetMapOpenStreetMap (OSM). A community-curated global map database (ODbL-licensed) with addr:* tagged features and place hierarchies. A secondary corpus source and a source of street names. data, with public transit, cycling routes, and place discovery, all in the browser with nothing to install. We like it a lot.
Cartes doesn't parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. or resolve addresses itself. Its search box calls a self-hosted Photon instance, and for French addresses it merges in results from the national BAN address API. The client does clever work before the geocoder ever sees the query: it detects raw coordinates in several formats, Open Location Codes ("plus codes"), five-digit French postal codes, and even a "de X à Y" itinerary phrasing. Those detectors are a good idea, and we intend to borrow a few of them.
What the client can't fix is the layerlayerOne transformer block — attention plus a feed-forward network, with normalization and residual connections — applied to every position. Stacking layers lets the model build up richer representations; Mailwoman's encoder has 6. underneath. Photon doesn't parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. addresses, so Cartes grafts BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. onto it, gated by a streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels.-keyword list and a check that you're searching inside France. Every app that builds on a geocoder ends up writing a shim like this eventually, and it's the kind of code nobody enjoys maintaining.
That's the gap Mailwoman aims at. We sit under apps like Cartes rather than beside them:
@mailwoman/photon speaks the same /api contract their client already calls, from a SQLite file
instead of an Elasticsearch cluster, with a parser at the front door — so the address shim stops being
the app's problem.