Library / SDK
openvenues/libpostal avatar
openvenues/libpostal

libpostal: parsing street addresses in every language, and the build cost that comes with it

A C library for parsing/normalizing street addresses around the world. Powered by statistical NLP and open geo data.

4,899 stars471 forksCMIT

At a glance

What is it?
libpostal is a C library that turns free-form international addresses into normalized, machine-comparable fields. The parsing model is the strong part; the data download and the C build are what decide whether it fits your stack.
Who is it for?
Adopt libpostal when your pipeline already handles large local data files and you need one parser for many countries, and when a C build step in your image is acceptable. Do not adopt it if you need a hosted endpoint, a Windows-first install, or a geocoder that returns coordinates.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 140 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem libpostal solves: free-form addresses are not fields yet

The README frames the problem precisely: addresses and the locations they represent matter for maps, place search, transportation, delivery, check-ins and reviews, and yet "even the simplest addresses are packed with local conventions, abbreviations and context, making them difficult to index/query effectively with traditional full-text search engines." That is the gap. A user types something like a street, a house number, a district and a postcode in an order that depends on the country, and a full-text index treats the whole string as tokens with no structure.

libpostal's job is to convert those free-form strings into clean normalized forms suitable for machine comparison and full-text indexing. The README is explicit that this is not geocoding: "Though libpostal is not itself a full geocoder, it can be used as a preprocessing step to make any geocoding application smarter, simpler, and more consistent internationally." That distinction matters when you scope the project. You get structure and normalization, not latitude and longitude.

The audience is narrow but real. Teams doing record linkage, deduplication and address matching across countries, or teams preparing address strings before sending them to a geocoder, are the ones who benefit. The repository topics list address parsing, deduping, deduplication, record linkage and international support, which describes that audience better than any marketing line would.

Statistical NLP over open geo data, not a country-by-country rule file

The mechanism is stated in the description: statistical NLP and open geo data. The README points to two long introductory posts, "Statistical NLP on OpenStreetMap" and its follow-up for the 1.0 release, for the research behind the library. The practical consequence of that design is that the parser is trained rather than hand-written per country, which is why the README can claim a goal of understanding location-based strings "in every language, everywhere" without shipping a separate grammar for each of the many flags it displays.

The repository layout supports that reading. There is a data/ directory and a resources/ directory, plus current_parser_training_set and versions/ at the top level. A trained statistical parser needs model data at runtime, and those directories are where it lives. There is also a Makefile.am and a configure.ac, so the build is autotools-based, and a scripts/ directory that holds the data-fetching and training steps.

The core is pure C, and the README states that bindings for Python, Ruby, Go, Java, PHP and NodeJS are officially supported, with other languages easy to add. That is the architecture that matters for adoption: one native library, one set of model files, and thin wrappers per language. If you run two services in different languages, they share the same parsing behaviour instead of drifting apart.

Installing libpostal and parsing your first address

The build is autotools plus a bootstrap script. The repository has bootstrap.sh, configure.ac and Makefile.am, which is the standard sequence for a project of this shape: run the bootstrap script to generate the configure script, then configure, then make. The README excerpt available here does not print the exact build commands, so read the README and the scripts/ directory for the current data-download step before you run anything in production. The data download is a separate, long-running stage that fetches the model data used for training and parsing.

bash
./bootstrap.sh
./configure
make
make install

After installation, the Python binding is the most direct way to see the parser work. It is a separate repository, openvenues/pypostal, and it is listed in the README as officially supported. The README does not print the install command for that binding, so follow the binding's own README for the package name and current instructions.

With the binding installed, parsing returns a structured result rather than a string. The README does not print a sample call or output, so the exact import path and key names come from the binding's own documentation, not from this article. What you should expect is a list of labelled components covering the house number, road, neighbourhood, city, state and postcode. If the library cannot find its data files, loading fails rather than returning partial results, so a working parse is also your confirmation that the data step completed.

The build and the data download are the real adoption cost

libpostal is not a package you add to a requirements file and forget. The C library builds from source through autotools, and the statistical model needs data that the project fetches and prepares through its own scripts. That combination means a build host with enough disk and time, and a container image that carries the resulting data if you want reproducible deploys. For a small service, the data footprint is likely to dominate the image; for a batch job, the download is a one-time cost you can cache.

The Windows story is the second constraint. The repository carries .appveyor.yml and a windows/ directory, so Windows builds are part of the project's CI surface, but the primary build path documented in the repository is the autotools one. Teams on Linux containers will have a smoother time than teams targeting Windows desktops, and the search interest in a Windows build reflects that friction rather than a documented one-command installer.

The third constraint is scope. If your actual need is "give me the coordinates for this address," libpostal is the wrong tool on its own. The README says so directly. You would use it to normalize input before a geocoder, or to compare two address strings for linkage, not as a replacement for a geocoding service.

Where libpostal sits next to a geocoder or a cloud address API

The obvious alternative for many teams is a hosted geocoding or address-validation API. The difference in approach is not just deployment, it is what you get back. A hosted geocoder returns a canonical address plus coordinates and often a confidence score, and it owns the data updates. libpostal returns parsed components and normalized forms, runs entirely on your machines, and leaves the coordinate lookup to whatever geocoder you pair it with. If your requirement is a verified, deliverable address with a point on a map, a hosted service is the shorter path.

The second alternative is writing your own parser or maintaining per-country regular expressions. That works until you add a country whose address order or abbreviations do not match your patterns, at which point you are maintaining a grammar per locale. libpostal's trained approach trades that maintenance for a build and a data download. The trade is worth naming honestly: you exchange ongoing rule maintenance for a heavier initial setup and a dependency on the project's model data.

The third path is a language-specific address library. Those tend to be narrower in geographic coverage but easier to install. If you only ever handle one country, a single-country library is a reasonable choice, and libpostal's international training is effort you are not using.

Maintenance, releases and licence

The release history is worth reading before you plan upgrades. The most recent release listed is v1.1 (Walla Walla), dated 2018-05-09. Before that, v1.0.0 (Brooklyn 99) on 2017-04-07 and v0.3.4 (Quito) on 2017-02-09. The repository is not archived and the last push was on 2026-05-13, so work on the master branch continues even though tagged releases are years apart. For planning, that means you should expect to build from a commit rather than wait for a versioned artifact, and you should pin the commit you build against.

Upgrade cost is dominated by the data, not the code. A parser retrained on newer open geo data can change its output for the same input, so an upgrade is a behaviour change you should test against your own address corpus rather than assume is neutral. Budget for that comparison whenever you move to a newer commit or regenerate the data.

The code is MIT licensed, which is permissive and compatible with commercial use. The licence on the model data is a separate question, and the README does not state its terms in the excerpt available here. Check the data files and the resources/ directory for their own licensing before you ship, and treat that as a distinct review from the code licence. This is a description of what the repository shows, not legal advice.

Editorial conclusion

Adopt libpostal when your pipeline already handles large local data files and you need one parser for many countries, and when a C build step in your image is acceptable. Do not adopt it if you need a hosted endpoint, a Windows-first install, or a geocoder that returns coordinates. Before committing, verify three things in your own environment: that the data download completes on your build host, that the language binding you intend to use links against the library version you built, and that your deployment image size budget covers the model data. Also confirm the licence terms of the data files you download, not just the MIT licence of the code.

Frequently asked questions

What is libpostal?

It is a C library for parsing and normalizing street addresses around the world, using statistical NLP and open geo data. The README describes it as a preprocessing step for geocoding applications rather than a geocoder itself.

What is address parsing?

It is the step that turns a free-form address string into separate labelled components, such as house number, road, city and postcode. The README argues this matters because local conventions and abbreviations make raw addresses hard to index with traditional full-text search engines.

How do I install libpostal?

The repository uses autotools, starting with the bootstrap.sh script, then configure, make and make install. The model data is fetched and prepared separately, so check the README and the scripts/ directory for the current data step.

How do I use libpostal in Python?

Use the pypostal binding listed in the README as officially supported, then call the parse function with an address string. The result is a set of labelled address components rather than a single normalized string.

Is libpostal free?

The code is released under the MIT licence, which permits commercial use. The licence terms of the model data the project downloads are not stated in the README excerpt, so verify those separately.

Official sources

  1. Issues
  2. License: MIT
  3. openvenues/libpostal on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openvenues-libpostal.svg)](https://hysenlabs.com/projects/openvenues-libpostal)