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

@mountainpass/addressr

v3.3.2

Published

Australian Address Validation, Search and Autocomplete

Readme

Addressr

Addressr

The only open-source, free self-hosted Australian address validation API.

Australian Address Validation, Search and Autocomplete — addressr.io

GitHub license npm npm downloads

GitHub issues GitHub pull requests

About

Australian Address Validation, Search and Autocomplete powered by the Geocoded National Address File (G-NAF), Australia's authoritative address database with 15+ million addresses.

  • Validated addresses from the official G-NAF source
  • Real-time autocomplete with fuzzy matching
  • Locality, postcode, and state search for area pickers
  • Geocoding to latitude/longitude (optional)
  • Self-hosted or SaaS — your choice, your data
  • Open source — audit the code, customize as needed

Why Addressr

| | Addressr | Addressify | AddressFinder | Geoscape | Google Maps | | ---------------------------------- | -------- | ---------------------------------------- | ---------------------------------------------- | ------------------------------------ | ----------- | | Self-hosted | ✅ | ❌ | ❌ | ❌ | ❌ | | Open source | ✅ | ❌ | ❌ | ❌ | ❌ | | Free tier (unlimited, self-hosted) | ✅ | ❌ | ❌ | ❌ | ❌ | | G-NAF data source | ✅ | ✅ | ✅ | ✅ (creator) | ❌ | | Data sovereignty | ✅ | ❌ | ❌ | ❌ | ❌ | | MCP integration for AI assistants | ✅ | ❌ | ❌ | ❌ | ❌ |

Stop paying Google Maps for Australian addresses. Stop locking your data into third-party SaaS. Addressr gives you unlimited address validation on your own infrastructure, or a cheap hosted API if you prefer.

Quick Start

Use the Hosted API

The fastest way to get started. No infrastructure to manage.

  1. Get an API key at RapidAPI

  2. Search for an address:

    curl "https://addressr.p.rapidapi.com/addresses?q=1+george+st+sydney" \
      -H "x-rapidapi-key: YOUR_KEY" \
      -H "x-rapidapi-host: addressr.p.rapidapi.com"

Use with AI Assistants

Connect Addressr to Claude, Cursor, VS Code Copilot, or any MCP-compatible AI assistant.

{
  "mcpServers": {
    "addressr": {
      "command": "npx",
      "args": ["-y", "@mountainpass/addressr-mcp"],
      "env": { "RAPIDAPI_KEY": "your-key" }
    }
  }
}

Three tools available: search-addresses, get-address, and health. See @mountainpass/addressr-mcp for full setup instructions.

Self Hosted

Run Addressr on your own infrastructure for full control over your data.

  1. Install addressr

    npm install @mountainpass/addressr -g

    NOTE: If you are running windows, you'll need to use wsl

  2. Start open search. For example run

    docker pull opensearchproject/opensearch:1.3.20
    docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "plugins.security.disabled=true" opensearchproject/opensearch:1.3.20
  3. Start API server. In a second window run:

    export ELASTIC_PORT=9200
    export ELASTIC_HOST=localhost
    addressr-server-2
  4. Setup the env vars for the data loader. In a third window run:

    export ELASTIC_PORT=9200
    export ELASTIC_HOST=localhost
    export ADDRESSR_INDEX_TIMEOUT=30s
    export ADDRESSR_INDEX_BACKOFF=1000
    export ADDRESSR_INDEX_BACKOFF_INCREMENT=1000
    export ADDRESSR_INDEX_BACKOFF_MAX=10000
    1. Optional — enable geocodes by setting the following env vars for the data loader. In the third window run: NOTE: with geocodes enabled, indexing takes much longer and needs much more memory. Only turn them on if you need them. You can always add them later.
    export ADDRESSR_ENABLE_GEO=1
    export NODE_OPTIONS=--max_old_space_size=8196
    1. Optional — limit the addresses to a single state by setting the COVERED_STATES env var for the data loader. This dramatically speeds up indexing. For example, in the third window run:
    export COVERED_STATES=VIC,SA

    Valid values are:

    • ACT
    • NSW
    • NT
    • OT
    • QLD
    • SA
    • TAS
    • VIC
    • WA
  5. Run data Loader. In the third window run:

    addressr-loader
  6. OK, so we stretched the truth a bit with the "Quick Start" heading. The truth is that it takes quite a while to download, store and index the 15+ million addresses from data.gov.au. So make a coffee, or tea, or find something else to do and come back in about an hour when it's done.

  7. Search for an address using the command line

    curl -i http://localhost:8080/addresses?q=LEVEL+25,+TOWER+3
  8. An updated G-NAF is released every 3 months. Put addressr-loader in a cron job or similar to keep addressr regularly updated. Read What the loader caches first — on a persistent target directory the refresh depends on how the release is named upstream, and can need a manual step.

  9. Wire your address form up to the address-server api.

What the loader caches

The loader keeps three things under target (override the location with GNAF_DIR, which defaults to target/gnaf). Each is skipped independently when it already exists, so a partial cleanup can leave you re-indexing stale data:

| Path | Holds | Reused when | | --------------------------- | ------------------------------- | ------------------------------------------------------------ | | target/keyv-file.msgpack | the data.gov.au dataset listing | it is under a day old (up to 30 days if data.gov.au is down) | | target/gnaf/<release>.zip | the downloaded archive | a file of that exact name is readable | | target/gnaf/<release>/ | the extracted archive | a directory of that exact name exists |

Both skips are keyed on the release filename, which carries the release month — for example g-naf_may26_allstates_gda94_psv_1023.zip. So when a quarterly release lands under a new name, the loader downloads and extracts it automatically and no manual step is needed.

You only need to intervene when the filename has not changed — a re-issued release, or an archive that was corrupted on disk. In that case delete both the zip and the extracted directory, or the loader will skip the download and re-index the old data:

rm -rf target/gnaf/<release>.zip target/gnaf/<release>/

If you have just seen a new release announced but the loader still reports the previous one, the dataset listing is being served from the day-old cache. Delete target/keyv-file.msgpack to force a fresh look.

GNAF_DATUM selects which distribution to load, gda94 (the default) or gda2020. data.gov.au publishes both for every release. Changing it is not just a config flip: the caches above are keyed on the release filename, which embeds the datum, so a new datum downloads and extracts cleanly and looks like it worked, while the index still holds the old coordinates until you re-index every state. The two datums differ by roughly 1.8 metres.

A failed download leaves nothing behind: the archive is staged in target/gnaf/incomplete/ and only moved into place once the response has been verified as complete, so a refused or truncated fetch aborts with the failing URL and status rather than leaving a corrupt archive for the next run to trip over.

Self Hosted with Docker

The ghcr.io/mountain-pass/addressr image runs the same v2 API server. It is built on Distroless, so the image contains the Node runtime and addressr and nothing else — no shell, no package manager, no npm. The entrypoint is node, so a command you pass is a script path rather than a program name.

The image is published to the GitHub Container Registry as a public package, so it pulls anonymously with no docker login.

Start the API server (the ELASTIC_* env vars are the same as above):

docker run -p 8080:8080 -e ELASTIC_HOST=host.docker.internal ghcr.io/mountain-pass/addressr

Run the data loader. It needs a writable target directory for the G-NAF download and the dataset cache, so mount one; unlike the server, it cannot run with --read-only:

docker run -v "$PWD/target:/home/nonroot/target" -e ELASTIC_HOST=host.docker.internal \
  ghcr.io/mountain-pass/addressr \
  /opt/addressr/lib/node_modules/@mountainpass/addressr/bin/addressr-loader.js

There is no shell in the image, so docker exec ... sh will not work. Diagnose with docker logs, docker inspect, docker cp, and the /health endpoint.

Image tags

ghcr.io/mountain-pass/addressr:latest is the tag to pull for the newest build. Every build also gets an immutable :<version>-<gitsha> tag, and a package release additionally gets a bare :<version> tag such as ghcr.io/mountain-pass/addressr:3.0.2. Pin the -<gitsha> tag if you want a build that can never be re-pointed under you; the bare :<version> and :latest tags can move to a rebuilt image.

Publishing is automatic, per ADR 040: a package release publishes all three tags, and a Docker-only change publishes :latest plus a new :<version>-<gitsha> without an npm release.

The image was previously published by hand to Docker Hub as mountainpass/addressr. That image is frozen and receives no further updates — switch any docker pull mountainpass/addressr to ghcr.io/mountain-pass/addressr.

Note that :latest moves. If you track it, watch the Docker image changelog — a change to the image no longer implies a new npm version, so it will not always show up in CHANGELOG.md.

API Endpoints

Addressr exposes a HATEOAS REST API. Start at the root (/) and follow links to discover endpoints. A supplementary OpenAPI 3.x spec is available at /api-docs.

| Endpoint | Purpose | Example | | ---------------------------- | ------------------------------------------------------------------ | --------------------------------- | | GET /addresses?q= | Search and autocomplete addresses | /addresses?q=1+george+st+sydney | | GET /addresses/{pid} | Get full address details (with links to locality, postcode, state) | /addresses/GAOT_717882967 | | GET /localities?q= | Search suburbs/localities by name | /localities?q=lilydale | | GET /localities/{pid} | Get locality details (with links to postcode, state) | /localities/loc9984d8beb142 | | GET /postcodes?q= | Search postcodes (q optional) | /postcodes?q=3140 | | GET /postcodes/{postcode} | Get postcode with associated localities | /postcodes/6798 | | GET /states?q= | Search states/territories (q optional) | /states?q=New | | GET /states/{abbreviation} | Get state details | /states/NSW | | GET /api-docs | OpenAPI 3.x specification | /api-docs | | GET /health | Health check | /health |

How it Works

How it works

Additional Settings

| Environment Variable | Value | Description | Default | | -------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------- | ------- | | ELASTIC_PROTOCOL | http | Connect to open search over http | ✅ | | ELASTIC_PROTOCOL | https | Connect to open search over https | | | ELASTIC_USERNAME | blank | Connect to open search without authentication | ✅ | | ELASTIC_USERNAME | non-blank | Connect to open search with the specified username | | | ELASTIC_PASSWORD | blank | Connect to open search without authentication | ✅ | | ELASTIC_PASSWORD | non-blank | Connect to open search with the specified password | | | PAGE_SIZE | 8 | Number or records to return in a search | ✅ | | ADDRESSR_ACCESS_CONTROL_ALLOW_ORIGIN | blank | An Access-Control-Allow-Origin response header is not returned | ✅ | | ADDRESSR_ACCESS_CONTROL_ALLOW_ORIGIN | non-blank | An Access-Control-Allow-Origin response header is returned with the value in the environment variable | | | ADDRESSR_ACCESS_CONTROL_EXPOSE_HEADERS | blank | An Access-Control-Expose-Headers response header is not returned | ✅ | | ADDRESSR_ACCESS_CONTROL_EXPOSE_HEADERS | non-blank | An Access-Control-Expose-Headers response header is returned with the value in the environment variable | | | ADDRESSR_ACCESS_CONTROL_ALLOW_HEADERS | blank | An Access-Control-Allow-Headers response header is not returned | ✅ | | ADDRESSR_ACCESS_CONTROL_ALLOW_HEADERS | non-blank | An Access-Control-Allow-Headers response header is returned with the value in the environment variable | | | ADDRESSR_PROXY_AUTH_HEADER | blank | No gateway auth header enforcement (self-hosted default) | ✅ | | ADDRESSR_PROXY_AUTH_HEADER | non-blank | Name of the header the origin requires — set alongside ADDRESSR_PROXY_AUTH_VALUE | | | ADDRESSR_PROXY_AUTH_VALUE | blank | No gateway auth header enforcement (self-hosted default) | ✅ | | ADDRESSR_PROXY_AUTH_VALUE | non-blank | Expected value the header must carry — set alongside ADDRESSR_PROXY_AUTH_HEADER | |

Gateway auth header (optional)

By default Addressr does not enforce any proxy authentication — self-hosted npm and Docker deployments work with zero configuration.

If you front Addressr with an API gateway (RapidAPI, Kong, Tyk, Apigee, AWS API Gateway, nginx, Caddy, or your own Cloudflare Worker) and want the origin to reject traffic that bypasses your gateway, set both environment variables to the header name your gateway injects and the shared secret it forwards:

| Variable | Example | Notes | | ---------------------------- | ------------------------- | ------------------------------------------- | | ADDRESSR_PROXY_AUTH_HEADER | X-RapidAPI-Proxy-Secret | Header name your gateway forwards | | ADDRESSR_PROXY_AUTH_VALUE | <your-gateway-secret> | Expected value; keep out of version control |

Behaviour:

  • Both unset → no enforcement (default).
  • Both set → requests without a matching header receive 401 Authentication required.
  • Exactly one set → the process exits at startup with a clear error (fails loud to prevent silent bypass).
  • /health and /api-docs remain reachable without the header so uptime monitors and gateway OpenAPI imports keep working.

See ADR 024 for the decision record.

NOTE: When adjusting PAGE_SIZE, you should take into account how quickly you want the initial results returned to the user. In many use cases, you want this to be as fast as possible. If you need show more results to the user, you are often better off leaving it a 8 and using the paging links to get more results while you are displaying the first 8.

Why is the default 8 and not 10? Mechanical Sympathy

System requirements

Open Search

opensearch >= 1.2.4 with 1.4GiB of memory

Addressr Loader

Default

Node.js >= 22 with 1GiB of memory

With Geocoding enabled

Node.js >= 22 with 8GiB of memory

Addressr Server

Node.js >= 22 with 64MiB of memory