What it is
ATS Storm Front is live severe weather for the whole United States: every active National Weather Service alert — from Tornado Warnings to Small Craft Advisories — drawn as color-coded polygons over the live NEXRAD base-reflectivity radar mosaic, both refreshed every five minutes. Tornado Warning polygons pulse red at roughly 30 fps; a "Most urgent" list keeps Extreme and Immediate alerts on top with live expires-in countdowns; severity chips and a ranked event-type list filter the map and lists together. On build day the feed carried 245 active alerts — of which only 42 had polygon geometry.
That last number is the app's defining honesty: roughly 80% of NWS alerts are zone-based and carry no polygon. Storm Front counts every alert in its lockup, stat strip, rankings, and urgent list (marking zone-only alerts with a pin-off icon) — and draws only the true polygons, rather than faking geometry or silently dropping the majority of the feed.
Everything is keyless: the NWS alerts API is public and CORS-open, the NEXRAD tiles come from the Iowa Environmental Mesonet's free cache, and the basemap is Esri's anonymous dark-gray vector style. The app runs with an empty .env.
The experience
The app opens on the continental United States with the radar mosaic already painting — green and amber cells drifting across the country — and alert polygons colored by warning family above it:
Like every app in the ATS branded line, the interface follows the house standard: React 19 and Tailwind 4 drive a dark glass shell, every control is a Lucide-iconed glass pod designed for this app, and there is no Esri widget chrome anywhere on screen. The map engine is Esri; the experience is ATS — designed, not assembled.
- Warning-family cartography. Tornado Warning red with a pulsing outline, Severe Thunderstorm amber, Flash Flood and Flood green-blue, the winter family ice-blue, the heat family orange, and everything else quiet slate — loud events win the eye and the hitTest.
- Live, twice over. The alerts feed refetches every five minutes and the radar layer is swapped for a fresh, cache-busted instance on the same cadence — plus a refresh-now pod.
- The urgent list. Extreme and Immediate alerts sorted to the top (severity → urgency → soonest expiry) with countdowns ticking every 15 seconds; clicking flies to the polygon, and zone-only alerts open their card without flying.
- Filters. Severity chips (Extreme / Severe / Moderate / Minor) and event types ranked by live count with class-colored dots — click to filter map and lists together.
- Glass detail cards. Severity, certainty, and urgency chips; effective-to-expires with a live countdown; the capped, scrollable description and instructions; and the issuing NWS office.
- Radar pods. Home (CONUS), a radar toggle, and a radar-opacity mini-slider.
The data — where it comes from
Both feeds are live, public, and keyless — verified on build day, including the API's undocumented sharp edges.
| Source | What it provides | Refresh | Cost | Attribution |
|---|---|---|---|---|
| NOAA NWS alerts API (api.weather.gov/alerts/active) | Every active US weather alert as GeoJSON (~1.3 MB, ~245 features on build day): event, severity, urgency, headline, times, description, polygon geometry where issued | Live; app refreshes every 5 min | Free (public) | NOAA / National Weather Service |
| Iowa Environmental Mesonet NEXRAD N0Q tile cache | National base-reflectivity radar mosaic as XYZ tiles, regenerated ~every 5 minutes | Live; app swaps the layer every 5 min | Free (keyless) | IEM, Iowa State University; NOAA NEXRAD data |
| Esri dark-gray vector basemap | Anonymous legacy vector basemap | Esri-hosted | Free (anonymous) | Esri |
How it was assembled
The application is a fully static single-page app — no backend, no database, no server-side rendering. The stack is the shared ATS Labs branded-app baseline:
Module map — the codebase is small and deliberate; each file owns one concern:
Key engineering decisions
- The no-limit-parameter trap. The NWS endpoint rejects a limit query parameter with HTTP 400 (verified on build day) — so the app fetches the whole ~1.3 MB feed, which at ~245 features is entirely manageable, rather than tripping the trap.
- Honest about zone alerts: 42 polygons out of 245. On build day 203 of 245 active alerts carried geometry: null — they are zone-based. Every alert still counts in the stats, rankings, and urgent list (zone-only entries wear a pin-off icon); only features with actual Polygon geometry are drawn. The parser keys on the geometry type defensively even though only plain Polygons were observed.
- Radar refresh means a new layer, not a mutated one. Mutating a WebTileLayer's urlTemplate does not refetch tiles — so every refresh constructs a fresh layer whose template carries a ?_=<timestamp> cache-buster, adds it at index 0, and only then removes the stale layer, so the radar never flashes to empty. The refresh-now pod and the 5-minute timer share this one code path, and visibility/opacity are re-applied from refs at construction so a swap never resets them.
- A memoized tornado pulse. Allocating a fill symbol per polygon per frame would thrash the garbage collector at 30 fps. Instead the pulse phase is quantized to 16 steps with one shared symbol per step across all Tornado Warning graphics — only graphic.symbol is swapped. The warnings pulse in sync, which reads as an alarm; that is the point. Tornado polygons live only in the pulse layer, never double-filled in the static layer.
- Defensive CAP handling. CAP severity includes "Unknown" (7 alerts on build day) — the filter maps it onto the Minor chip so no alert can vanish with no chip to bring it back; unparsable expiry times sort last (fallback Infinity) instead of first; NWS timestamps carry local offsets and are rendered viewer-local, with Zulu reserved for the lockup's radar/updated stamps.