Quick start • Schema 1.1 upgrade • Document schema • Build • Documentation
New NSW ward coverage: Camden is the first qualified council; other gaps remain explicit. See NSW ward sources and coverage.
flat-white turns Australian G-NAF address data into one JSON document per principal address. Each document brings together address text, geocodes, locality details, aliases and administrative and census boundaries. Download a state, read one line at a time, and use the data without recreating the source joins.
It suits address search, bulk imports and geographic analysis. NDJSON is the published download format; the code also provides Parquet and GeoParquet converters for local use.
Schema 1.0.0 change: mesh block, SA1–SA4 and GCCSA now use ASGS 2026. Their JSON shapes are unchanged, but their geographic meanings can differ. Read the migration guide before upgrading. Check each release's metadata: this README describes the current code, while previously published schema 0.x downloads retain ASGS 2021.
New in 1.1.0: separate fallback coordinates, stable site-point selection and corrected GeoParquet CRS metadata. The upgrade guide explains what consumers should change. Published releases retain their own schema version.
You need the GitHub CLI, jq and gzip. Choose a release
once, download its metadata, and check compatibility before downloading addresses.
Run these steps in a fresh directory so files from different releases stay separate.
# Resolve one tag. You can instead set TAG to a specific published release.
TAG=$(gh api repos/jbejenar/flat-white/releases/latest --jq '.tag_name')
gh release download "$TAG" --repo jbejenar/flat-white --pattern metadata.json# Stop here if this fails: that release is not the contract used by this guide.
jq -e '(.schemaVersion == "1.0.0" or .schemaVersion == "1.1.0") and .asgsYear == 2026' metadata.jsonThe check will fail if the latest published release is still schema 0.x. Select a published 1.x release supported by this guide, or keep using the older release with its matching schema and ASGS 2021 references. Do not change the metadata to bypass this check.
# Download Victoria from the same tag.
RELEASE_VERSION=$(jq -r '.version' metadata.json)
FILE="flat-white-${RELEASE_VERSION}-vic.ndjson.gz"
gh release download "$TAG" --repo jbejenar/flat-white --pattern "$FILE"
# Show a few Melbourne addresses. This parses JSON; it does not validate the schema.
gzip -cd "$FILE" | jq -c 'select(.postcode == "3000")' | head -n 3Browse available files and their source versions on the releases page. Use the release metadata for counts rather than relying on estimates in a README.
Each NDJSON line is a complete address document. This shortened, synthetic fixture example shows the census fields most affected by the migration:
{
"_version": "2026.02",
"boundaries": {
"meshBlock": {
"code": "29900000083",
"category": "Residential"
},
"sa1": "29901000103",
"sa2": {
"name": "Fixture 2026 SA2",
"code": "299010001"
},
"sa3": {
"name": "Fixture 2026 SA3",
"code": "29901"
},
"sa4": {
"name": "Fixture 2026 SA4",
"code": "299"
},
"gccsa": {
"name": "Fixture 2026 GCCSA",
"code": "2TEST"
}
}
}The fixture deliberately keeps February 2026 addresses and adds synthetic 2026
census assignments. Those codes are test data, not real ABS assignments.
Production schema 1.x builds require compatible sources from August 2026 or later.
A document's _version records the G-NAF quarter, not the schema or ASGS year.
The document schema defines every field and its
nullability. Field provenance traces each value to its
source. A missing boundary or geocode is represented by null; do not assume
every address has every enrichment.
Continue with FILE set by the quick start:
# Check the compressed stream, then compare Victoria's row count with metadata.
gzip -t "$FILE"
ACTUAL=$(gzip -cd "$FILE" | wc -l | tr -d '[:space:]')
EXPECTED=$(jq -r '.states.VIC' metadata.json)
test "$ACTUAL" = "$EXPECTED"For document validation, use a checkout matching the release's schema, install
its dependencies and run npm run build. Run this from the directory containing
the downloaded state file and its metadata.json:
node /path/to/flat-white/dist/verification-report.js . \
--states VIC --output verification-report.mdReplace /path/to/flat-white with that checkout's path. The report streams the
compressed file, validates every document, checks state membership and reports
coverage for all census levels. The commands above check integrity, counts and
the document schema; they do not prove that an external geographic join uses the
right edition. The migration checklist
covers that part.
- Discover and freeze the G-NAF and Admin Boundaries source versions for the run.
- Start temporary Postgres with PostGIS, then load the sources with the pinned gnaf-loader.
- Prepare boundaries, spatially assign administrative areas, and look up census areas through the address's 2026 mesh-block code.
- Join and stream the address documents, validating each one with Zod.
- Verify the output, split it by state and compress it. Stop Postgres when done.
The boundary guide explains the two enrichment methods. Postgres is a build tool, not a database service you need to run to consume the files.
For development, use the committed fixture. It exercises preparation, spatial
joins, both flatten SQL paths, schema checks and the regression baseline without
a national download. Use the pinned Node.js 22.22.1 in .nvmrc and Docker with
Compose. Supported Node versions: 22.22.1 through 22.x, 24.x and 26.x.
Dependency compatibility: npm now rejects packages that require an unsupported
Node version, both locally and in the Docker build. Node type definitions follow
the Node 22 runtime. Parquet stays at @dsnp/parquetjs 1.8.8 because newer releases
require Node 24.18 or later; upgrading it needs a coordinated runtime migration.
git clone --recurse-submodules https://github.com/jbejenar/flat-white.git
cd flat-white
npm ci
./scripts/build-fixture-only.shOutput goes to output/fixture.ndjson. Leave GNAF_VERSION unset for this command;
the fixture uses its frozen 2026.02 snapshot. See contributor instructions
and the fixture guide.
To exercise the container with the same small fixture:
docker build -t flat-white .
mkdir -p output
docker run --rm -v "$PWD/output:/output" flat-white --fixture-only --output /outputA production build processes the full source archives. New source-lock requirement: acquire them once before starting the container. Each build checks the archives against the recorded checksums. This example builds Victoria from August 2026; use the small fixture above for development.
npm run build
GNAF_VERSION=2026.08 ADMIN_BDYS_VERSION=2026.08 node dist/source-lock.js acquire
mkdir -p output
docker run --rm -e GNAF_VERSION=2026.08 \
-v "$PWD/sources:/sources:ro" -v "$PWD/output:/output" \
flat-white --states VIC --compress --output /outputOmit --states for all states and territories. Both source quarters must be August
2026 or newer. The release guide
explains source discovery, exact-source rebuilds, boundary dates and cache validation.
Source locking makes build inputs traceable. The current writer is schema 1.1.0;
source provenance and the document contract are versioned separately.
The workflow checks upstream every Monday at 02:00 UTC and skips a quarter that already has a published or draft release. New source data is still quarterly; weekly discovery accommodates publication dates that move.
A production run builds ACT, NSW, NT, OT, QLD, SA, TAS, VIC and WA as separate jobs.
GitHub Releases carry per-state .ndjson.gz files, metadata.json and the document
schema. The combined national file is a workflow artifact, since it can exceed
GitHub's per-asset size limit. The configured S3 mirror publishes versioned files
and a manifest after the GitHub release is public. See release checks and S3 recovery.
Download all nine state files from the same checked tag with:
gh release download "$TAG" --repo jbejenar/flat-white --pattern 'flat-white-*-*.ndjson.gz'Keep the files together with their metadata. Avoid broad globs across old download directories: mixing quarters can duplicate addresses and mix geographic editions.
flat-white depends on Hugh Saalmans' gnaf-loader to turn government source files into a usable PostGIS database. This repository pins that work as a submodule and adds the flattened document contract, verification and release pipeline. Thank you, Hugh, for maintaining the foundation.
gnaf-loader also serves people who need the relational tables and spatial tooling. Choose the representation that fits your use case, and check the source quarter and geography edition before comparing outputs from different pipelines.
Start at the documentation index, or go directly to:
- Schema 1.1 upgrade — fallback precision, reader compatibility and corrected CRS.
- Migration to schema 1.0.0 / ASGS 2026 — impact, upgrade checks and rollback.
- Document schema — fields, types, nulls and version metadata.
- Field provenance and boundary processing.
- Release procedure, runbook and loader updates.
- Fixtures, architectural decisions and current work.
- Changelog and historical roadmap.
Sources: G-NAF and Administrative Boundaries. Source data has its own licensing terms; the code licence does not replace them.
G-NAF © Geoscape Australia licensed by the Commonwealth of Australia under the Open G-NAF End User Licence Agreement.
Administrative Boundaries © Geoscape Australia licensed by the Commonwealth of Australia under CC BY 4.0.
Code: Apache 2.0.