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

@mailwoman/libpostal

v6.4.0

Published

libpostal drop-in — a libpostal-compatible parse/expand HTTP API over Mailwoman's neural address parser. The lowest-dependency drop-in: parse needs no gazetteer. Run it with `npx @mailwoman/libpostal serve`.

Readme

@mailwoman/libpostal

A libpostal-compatible parse/expand HTTP API over Mailwoman's neural address parser. The lowest-dependency drop-in — /parse needs no gazetteer, just the model.

npx @mailwoman/libpostal serve --port 8081
curl -s "http://localhost:8081/parse?query=1600 Pennsylvania Ave NW, Washington DC 20500"
# [{"label":"house_number","value":"1600"},{"label":"road","value":"Pennsylvania Ave NW"},
#  {"label":"city","value":"Washington"},{"label":"state","value":"DC"},{"label":"postcode","value":"20500"}]

Endpoints

| Endpoint | libpostal contract | | --------------- | -------------------------------------------------------------- | | / | HTML landing page (endpoint index + example queries) | | /parse | parse_address — ordered [{label, value}] components | | /expand | expand_address — normalized forms (see the honest note) | | /openapi.json | the emitted OpenAPI 3.1 document — the spec, not a copy of one |

/parse maps Mailwoman's ComponentTag classifications to libpostal's labels (streetroad, localitycity, regionstate, …) via COMPONENT_TO_LIBPOSTAL. Both /parse and /expand accept GET (query string) or POST (JSON body) — the JSON body is parsed natively, no middleware to mount.

Honest note on /expand: Mailwoman's normalization is deterministic, so /expand returns the original plus its normalized + abbreviation-expanded forms — not libpostal's probabilistic multi-variant expansion. One canonical alternative, not a hypothesis set.

Library use

import { serveNode } from "@mailwoman/api-kit"
import { createLibpostalApp, type LibpostalEngine } from "@mailwoman/libpostal"

const engine: LibpostalEngine = {
	async parse(query) {
		/* return [{ classification, value }] from your parser */
	},
}
const app = createLibpostalApp(engine)

serveNode({ fetch: app.fetch, port: 8081, hostname: "0.0.0.0" })

createLibpostalApp returns a plain fetch-shaped Hono app — deploy it behind any web-standard runtime (edge, Workers, Deno); serveNode is only the Node listener wrapper.

CORS

Browser clients call this cross-origin — including the preflighted POST /parse — so the server sends permissive CORS by default: Access-Control-Allow-Origin: * and a 204 answer to preflight OPTIONS. Behind a reverse proxy that already sets the headers, turn it off with --no-cors (or createLibpostalApp(engine, { cors: false })).