Area selector
Search by neighborhood or ZIP and keep all other panels in sync with that selection.
Static-first app blueprint
A neighborhood safety web app can absolutely run with minimal server-side
computation if we move the heavy work into a nightly build. Pull incidents with
tidycops, pre-aggregate them once, publish static files, and let the browser
handle light filtering.
Why this works
The app does not need to calculate summaries, joins, or crime classifications on every page load. It only needs to load the already-built files for the selected place and time window.
Best first city
Start with one city, one set of boundaries, and one recent-window feed. Expand to more cities after the data pipeline and UI contract feel stable.
MVP
Pipeline
A nightly GitHub Actions workflow can pull incidents, normalize fields, join them to your neighborhood and ZIP boundaries, compute summaries, and write static files back into the repository. The live app then becomes a static site that fetches those outputs directly.
This makes GitHub Actions your cron job, the repository your lightweight data store, and GitHub Pages your host. It is a good fit for a civic dashboard that updates daily rather than minute by minute.
Data contract
metadata.jsonBuild timestamp, city name, date window, and high-level caveats for the UI.
summary_by_area.jsonOne row per geography with total incidents, violent incidents, property incidents, and rates if available.
offense_mix.jsonTop offense categories by area and crime group for quick bar charts.
time_patterns.jsonHour-of-day and day-of-week aggregates for overall, violent, and property patterns.
place_types.jsonMost common location contexts like street, residence, parking lot, transit, or business.
actions_by_profile.jsonPrepared recommendation text keyed to the pattern mix for residents, businesses, police, and city government.
neighborhoods.geojsonBoundary polygons the browser can draw and use for hover, click, and labeling.
incidents_recent.parquetAn optional recent incidents extract for point maps, debugging, and deeper drill-down views.
Interpretation
The safest framing is to show environmental context layers rather than claiming a place causes crime. Parks, liquor licenses, transit stops, large parking lots, corridors, or vacant parcels may correlate with where incidents are recorded, but the app should present these as nearby features for interpretation, not blame.
A good wording pattern is: “Features often found near recent incident concentrations” followed by a short methods note and a reminder that correlation is not causation.
Action panels
Dashboard
Repo starter
This repo now includes a starter GitHub Actions workflow at
.github/workflows/nightly-neighborhood-watch-data.yml, an R build
scaffold at scripts/build_neighborhood_watch_data.R, and a data folder
contract at data/neighborhood-watch/.
The app above reads static JSON outputs from the nightly build. Try searching for a neighborhood or ZIP code once the first build completes.