NJ Parcel Flood Risk Dashboard
Flood exposure for all 3,478,722 New Jersey parcels, scored 0–100 and served with no backend.
- 3,478,722Parcels scored statewide
- 19.31%Parcels at risk
- 25.86%Assessed value exposed
- 1.89 hStatewide intersect, against a 12 h budget
Problem
New Jersey publishes everything you need in order to know whether a property sits in harm’s way — parcel geometry, MOD-IV tax assessments, FEMA’s flood hazard layer, NJDEP’s sea-level-rise projections, NFIP claims history. It publishes them as five unrelated datasets, at five different grains, none of which will join to another without work.
So the practical question — which parcels are exposed, how much value is behind them, and why does this one score what it scores — is answerable in principle and nobody’s job in practice. This dashboard is that join, done once, statewide, at parcel grain.

Approach
Every parcel’s score is a weighted composite of three components, each normalised to the unit interval before weighting:
score = round(100 × (0.45·C_cur + 0.30·C_fut + 0.25·C_loss))
- C_cur — overlap with FEMA’s Special Flood Hazard Area today, with a presence floor so a barely-touched parcel does not score misleadingly low.
- C_fut — overlap with NJDEP’s projected future flood layers. Where that data does not cover a parcel it is estimated as half of C_cur and labelled as such — never presented as “no future risk.”
- C_loss — the parcel’s census tract’s NFIP claims history, as a statewide percentile.
Scores sort into five bands, and every parcel’s detail panel shows the full breakdown. That “why is this number what it is” requirement drove the whole schema: a score a user cannot take apart is a score they should not trust.

Technical detail — the precompute-everything architecture
There is no server and no runtime geoprocessing. The heavy work runs locally, partitioned by county and resumable, so a failure never restarts finished work:
- Pipeline — Python with
uv, DuckDB with its spatial extension, and GeoPandas: parcel core → flood-layer normalisation → statewide intersections → scoring → aggregates → PMTiles generation → search index → validation. - Tiles — tippecanoe in Docker producing PMTiles, served straight from object storage over HTTP range requests. No tile server runs anywhere.
- App — Vite, React 18, TypeScript, Tailwind v4, MapLibre GL. Five views: search and map, jurisdiction summary, district exposure, ranked municipalities, methodology. Statewide address geocoding runs against New Jersey’s own government geocoder.
- Hosting — Cloudflare Pages for the app, R2 for tiles, search shards, and summaries. Zero egress fees matter here: the map data alone is most of a gigabyte on every real session.
Two privacy rules are absolute. No owner names or mailing addresses appear in any published artifact. And NFIP loss evidence is aggregated to census tract, never to parcel — the redacted claims dataset does not support parcel-level precision, and pretending it does would be both wrong and a privacy failure.
Results
Run statewide, either lens, all property classes:
- 671,829 of 3,478,722 parcels — 19.31% — are at risk.
- 25.86% of assessed value is exposed.

That utility-and-infrastructure result is plausible rather than alarming: siting is often water-adjacent for practical reasons. Residential sitting lowest on both measures is consistent with its being the most widespread and least water-concentrated class statewide.

What the build cost, and what it got wrong
The heaviest stage — statewide parcel-to-flood intersections — completed in 1.89 hours against a 12-hour budget. That is the easy number to report. These are the others.
- 6 of 7 publication gates pass. The seventh ships as a disclosed limitation. The statewide MOD-IV join rate lands at 88.34%, below the project’s own 97% target. It is logged and carried forward rather than papered over or quietly relaxed.
- A rule that passed every targeted test and still broke real towns. Fixing a
municipality name-matching gap, a general
RIVER→RIVabbreviation rule looked correct against every synthetic test written for it — and quietly broke River Vale and River Edge, whose names fuse the word into one token (RIVERVALE). Caught by re-verifying against the full statewide dataset rather than trusting the test suite, then reverted to a narrow explicit override for the one town that needed it. - Deploying for real caught what dev testing could not. The production build silently
failed to ship MapLibre’s own worker script. The first fix looked complete — file shipped,
correct MIME type — but the worker still died on load, invisible to console-error
checking. Found through Playwright’s worker-lifecycle API showing
createdthenclosedwithin milliseconds. - A shipped feature, reverted on UX grounds rather than technical ones. Widening the tileset so parcel mode could zoom out as far as municipality mode was a real, working, verified fix. It was reverted the same day anyway: at that zoom the view stopped reading as “the flood layer” the way the continuous municipality choropleth did. Correct code is not automatically the right product decision.
Automated accessibility and end-to-end testing (Playwright with axe-core) covers search,
filter cascades, chart-versus-data consistency, and CSV export across 16 tests, with zero
serious accessibility violations. Running the suite for real — not merely writing it —
caught defects no amount of manual spot-checking surfaced, including an interactive button
nested inside an ARIA option element.
Data sources
| Dataset | Source |
|---|---|
| Parcel geometry + MOD-IV attributes | NJGIN/NJOGIS Parcels and MOD-IV Composite of NJ |
| Current flood hazard | FEMA National Flood Hazard Layer |
| Future flood indicators | NJDEP climate-adjusted / sea-level-rise layers |
| NFIP loss evidence | OpenFEMA FIMA NFIP Redacted Claims, tract-level |
| Boundaries | Census TIGER counties and municipalities |
| Address geocoding | New Jersey’s own ArcGIS geocoder (geo.nj.gov) |
Screening tool — not a flood determination. Scores are relative screening indicators, not insurance ratings, legal flood-zone determinations, or property valuations.
Share this page
https://abdulkalam.pages.dev/projects/nj-parcel-flood-risk/
Scan to open this page. Download the SVG for print.