# mitchross/radar-ng architecture

> Architecture diagram of the GitHub repository mitchross/radar-ng, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mitchross/radar-ng
- Repository: https://github.com/mitchross/radar-ng

## Overview

radar-ng is a self-hosted weather-radar and weather-data product: Temporal-driven workers ingest public radar, forecast, air-quality, lightning, and tropical data, render tiles, and serve them to an Expo app. Users select a location and inspect radar timelines, nowcasts, forecasts, alerts, and map overlays; the app also supports CarPlay, watch, and widget experiences. The graph preserves documented capabilities, but some subsystem links are intentionally broad because their implementation files were not sampled.

Main entry points: [`temporal/workflows`](https://github.com/mitchross/radar-ng/tree/master/temporal/workflows) (Ingest workflows), [`frontend/src/app/(tabs)/index.tsx`](https://github.com/mitchross/radar-ng/blob/master/frontend/src/app/(tabs)/index.tsx) (Expo app), [`backend/shared/tiler.py`](https://github.com/mitchross/radar-ng/blob/master/backend/shared/tiler.py) (Tile rendering), [`frontend/src/app/(tabs)`](https://github.com/mitchross/radar-ng/tree/master/frontend/src/app/(tabs)) (Weather screens)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Weather clients"]
  node_mobile["Expo app<br/>[index.tsx]"]
  node_map["Weather map<br/>[WeatherMap.tsx]"]
  node_screens["Weather screens"]
  node_clienthooks["Weather data hooks"]
  node_carplay["CarPlay navigation"]
  node_watchwidget["Watch and widget"]
end

subgraph group_api["API and access"]
  node_api["FastAPI service<br/>[server.py]"]
  node_placealerts["Places and alerts API<br/>[routes_places.py]"]
  node_workflowapi["Workflow API"]
  node_staticserver["Static tile serving"]
end

subgraph group_orchestration["Temporal orchestration"]
  node_schedules["Temporal schedules<br/>[seed.py]"]
  node_worker["Temporal workers<br/>[worker.py]"]
  node_workflows["Ingest workflows"]
  node_watchworkflow["Storm watch workflow<br/>[watch_storm.py]"]
end

subgraph group_ingestion["Data ingestion"]
  node_mrms["MRMS radar ingest<br/>[activities.py]"]
  node_hrrr["HRRR forecast ingest<br/>[activities.py]"]
  node_openmeteo["Open-Meteo sync<br/>[activities.py]"]
  node_airquality["Air-quality ingest<br/>[activities.py]"]
  node_lightning["Lightning ingest<br/>[activities.py]"]
  node_tropical["Tropical ingest<br/>[activities.py]"]
  node_nowcast["Radar nowcast<br/>[activities.py]"]
end

subgraph group_storage["Tile and state storage"]
  node_tiling["Tile rendering<br/>[tiler.py]"]
  node_manifest[("Tile manifest<br/>[manifest.py]")]
  node_tilefiles[("Rendered tile files")]
end

node_person(("Weather user"))
node_nws["NWS services"]
node_photon["Photon geocoder"]
node_temporal["Temporal service"]
node_publicdata["Public data sources"]
node_push["Push notification service"]

node_person -->|"uses"| node_mobile
node_mobile -->|"opens"| node_screens
node_screens -->|"displays"| node_map
node_screens -->|"requests data"| node_clienthooks
node_clienthooks -->|"calls"| node_api
node_api -->|"routes"| node_placealerts
node_api -->|"routes"| node_workflowapi
node_placealerts -->|"fetches alerts"| node_nws
node_placealerts -.->|"geocodes"| node_photon
node_workflowapi -->|"starts and queries"| node_temporal
node_schedules -->|"creates schedules"| node_temporal
node_temporal -->|"dispatches tasks"| node_worker
node_worker -->|"registers workflows"| node_workflows
node_workflows -->|"runs activities"| node_mrms
node_workflows -->|"runs activities"| node_hrrr
node_workflows -->|"runs activities"| node_openmeteo
node_workflows -->|"runs activities"| node_airquality
node_workflows -->|"runs activities"| node_lightning
node_workflows -->|"runs activities"| node_tropical
node_workflows -->|"runs activities"| node_nowcast
node_worker -->|"registers workflow"| node_watchworkflow
node_mrms -->|"fetches radar"| node_publicdata
node_hrrr -->|"fetches forecast"| node_publicdata
node_openmeteo -->|"syncs forecast"| node_publicdata
node_airquality -->|"fetches air quality"| node_publicdata
node_lightning -->|"fetches lightning"| node_publicdata
node_tropical -->|"fetches tropical data"| node_publicdata
node_mrms -->|"renders tiles"| node_tiling
node_hrrr -->|"renders tiles"| node_tiling
node_airquality -->|"renders tiles"| node_tiling
node_tiling -->|"writes tiles"| node_tilefiles
node_workflows -->|"publishes layers"| node_manifest
node_staticserver -->|"serves tiles"| node_tilefiles
node_staticserver -->|"serves manifest"| node_manifest
node_clienthooks -->|"fetches map data"| node_staticserver
node_mobile -->|"supports navigation"| node_carplay
node_mobile -->|"shares radar data"| node_watchwidget
node_watchworkflow -.->|"sends notifications"| node_push

click node_mobile "https://github.com/mitchross/radar-ng/blob/master/frontend/src/app/(tabs)/index.tsx"
click node_map "https://github.com/mitchross/radar-ng/blob/master/frontend/src/components/map/WeatherMap.tsx"
click node_screens "https://github.com/mitchross/radar-ng/tree/master/frontend/src/app/(tabs)"
click node_clienthooks "https://github.com/mitchross/radar-ng/tree/master/frontend/src/hooks"
click node_carplay "https://github.com/mitchross/radar-ng/tree/master/frontend/targets/carplay"
click node_watchwidget "https://github.com/mitchross/radar-ng/tree/master/frontend/targets/watch"
click node_api "https://github.com/mitchross/radar-ng/blob/master/backend/api/api/server.py"
click node_placealerts "https://github.com/mitchross/radar-ng/blob/master/backend/api/api/routes_places.py"
click node_workflowapi "https://github.com/mitchross/radar-ng/blob/master/backend/api/api/routes_workflows.py"
click node_schedules "https://github.com/mitchross/radar-ng/blob/master/temporal/schedules/seed.py"
click node_worker "https://github.com/mitchross/radar-ng/blob/master/temporal/worker.py"
click node_workflows "https://github.com/mitchross/radar-ng/tree/master/temporal/workflows"
click node_watchworkflow "https://github.com/mitchross/radar-ng/blob/master/temporal/workflows/watch_storm.py"
click node_mrms "https://github.com/mitchross/radar-ng/blob/master/backend/ingest_mrms/activities.py"
click node_hrrr "https://github.com/mitchross/radar-ng/blob/master/backend/ingest_hrrr/activities.py"
click node_openmeteo "https://github.com/mitchross/radar-ng/blob/master/backend/open_meteo_sync/activities.py"
click node_airquality "https://github.com/mitchross/radar-ng/blob/master/backend/ingest_airquality/activities.py"
click node_lightning "https://github.com/mitchross/radar-ng/blob/master/backend/ingest_lightning/activities.py"
click node_tropical "https://github.com/mitchross/radar-ng/blob/master/backend/ingest_tropical/activities.py"
click node_nowcast "https://github.com/mitchross/radar-ng/blob/master/backend/nowcast/activities.py"
click node_tiling "https://github.com/mitchross/radar-ng/blob/master/backend/shared/tiler.py"
click node_manifest "https://github.com/mitchross/radar-ng/blob/master/backend/shared/manifest.py"
click node_tilefiles "https://github.com/mitchross/radar-ng/tree/master/backend"
click node_staticserver "https://github.com/mitchross/radar-ng/tree/master/backend"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_mobile,node_map,node_screens,node_clienthooks,node_carplay,node_watchwidget,node_person toneBlue
class node_api,node_placealerts,node_workflowapi,node_staticserver toneAmber
class node_schedules,node_worker,node_workflows,node_watchworkflow toneMint
class node_mrms,node_hrrr,node_openmeteo,node_airquality,node_lightning,node_tropical,node_nowcast toneRose
class node_tiling,node_manifest,node_tilefiles,node_nws,node_photon,node_temporal,node_publicdata,node_push toneIndigo
```

## Components

### Weather clients

- [Expo app](https://github.com/mitchross/radar-ng/blob/master/frontend/src/app/(tabs)/index.tsx): `frontend/src/app/(tabs)/index.tsx`
- [Weather map](https://github.com/mitchross/radar-ng/blob/master/frontend/src/components/map/WeatherMap.tsx): `frontend/src/components/map/WeatherMap.tsx`
- [Weather screens](https://github.com/mitchross/radar-ng/tree/master/frontend/src/app/(tabs)): `frontend/src/app/(tabs)`
- [Weather data hooks](https://github.com/mitchross/radar-ng/tree/master/frontend/src/hooks): `frontend/src/hooks`
- [CarPlay navigation](https://github.com/mitchross/radar-ng/tree/master/frontend/targets/carplay): `frontend/targets/carplay`
- [Watch and widget](https://github.com/mitchross/radar-ng/tree/master/frontend/targets/watch): `frontend/targets/watch`

### API and access

- [FastAPI service](https://github.com/mitchross/radar-ng/blob/master/backend/api/api/server.py): `backend/api/api/server.py`
- [Places and alerts API](https://github.com/mitchross/radar-ng/blob/master/backend/api/api/routes_places.py): `backend/api/api/routes_places.py`
- [Workflow API](https://github.com/mitchross/radar-ng/blob/master/backend/api/api/routes_workflows.py): `backend/api/api/routes_workflows.py`
- [Static tile serving](https://github.com/mitchross/radar-ng/tree/master/backend): `backend`

### Temporal orchestration

- [Temporal schedules](https://github.com/mitchross/radar-ng/blob/master/temporal/schedules/seed.py): `temporal/schedules/seed.py`
- [Temporal workers](https://github.com/mitchross/radar-ng/blob/master/temporal/worker.py): `temporal/worker.py`
- [Ingest workflows](https://github.com/mitchross/radar-ng/tree/master/temporal/workflows): `temporal/workflows`
- [Storm watch workflow](https://github.com/mitchross/radar-ng/blob/master/temporal/workflows/watch_storm.py): `temporal/workflows/watch_storm.py`

### Data ingestion

- [MRMS radar ingest](https://github.com/mitchross/radar-ng/blob/master/backend/ingest_mrms/activities.py): `backend/ingest_mrms/activities.py`
- [HRRR forecast ingest](https://github.com/mitchross/radar-ng/blob/master/backend/ingest_hrrr/activities.py): `backend/ingest_hrrr/activities.py`
- [Open-Meteo sync](https://github.com/mitchross/radar-ng/blob/master/backend/open_meteo_sync/activities.py): `backend/open_meteo_sync/activities.py`
- [Air-quality ingest](https://github.com/mitchross/radar-ng/blob/master/backend/ingest_airquality/activities.py): `backend/ingest_airquality/activities.py`
- [Lightning ingest](https://github.com/mitchross/radar-ng/blob/master/backend/ingest_lightning/activities.py): `backend/ingest_lightning/activities.py`
- [Tropical ingest](https://github.com/mitchross/radar-ng/blob/master/backend/ingest_tropical/activities.py): `backend/ingest_tropical/activities.py`
- [Radar nowcast](https://github.com/mitchross/radar-ng/blob/master/backend/nowcast/activities.py): `backend/nowcast/activities.py`

### Tile and state storage

- [Tile rendering](https://github.com/mitchross/radar-ng/blob/master/backend/shared/tiler.py): `backend/shared/tiler.py`
- [Tile manifest](https://github.com/mitchross/radar-ng/blob/master/backend/shared/manifest.py): `backend/shared/manifest.py`
- [Rendered tile files](https://github.com/mitchross/radar-ng/tree/master/backend): `backend`

### Other components

- **Weather user**
- **NWS services**
- **Photon geocoder**
- **Temporal service**
- **Public data sources**
- **Push notification service**

## Connections

- Weather user → Expo app: uses
- Expo app → Weather screens: opens
- Weather screens → Weather map: displays
- Weather screens → Weather data hooks: requests data
- Weather data hooks → FastAPI service: calls
- FastAPI service → Places and alerts API: routes
- FastAPI service → Workflow API: routes
- Places and alerts API → NWS services: fetches alerts
- Places and alerts API → Photon geocoder: geocodes
- Workflow API → Temporal service: starts and queries
- Temporal schedules → Temporal service: creates schedules
- Temporal service → Temporal workers: dispatches tasks
- Temporal workers → Ingest workflows: registers workflows
- Ingest workflows → MRMS radar ingest: runs activities
- Ingest workflows → HRRR forecast ingest: runs activities
- Ingest workflows → Open-Meteo sync: runs activities
- Ingest workflows → Air-quality ingest: runs activities
- Ingest workflows → Lightning ingest: runs activities
- Ingest workflows → Tropical ingest: runs activities
- Ingest workflows → Radar nowcast: runs activities
- Temporal workers → Storm watch workflow: registers workflow
- MRMS radar ingest → Public data sources: fetches radar
- HRRR forecast ingest → Public data sources: fetches forecast
- Open-Meteo sync → Public data sources: syncs forecast
- Air-quality ingest → Public data sources: fetches air quality
- Lightning ingest → Public data sources: fetches lightning
- Tropical ingest → Public data sources: fetches tropical data
- MRMS radar ingest → Tile rendering: renders tiles
- HRRR forecast ingest → Tile rendering: renders tiles
- Air-quality ingest → Tile rendering: renders tiles
- Tile rendering → Rendered tile files: writes tiles
- Ingest workflows → Tile manifest: publishes layers
- Static tile serving → Rendered tile files: serves tiles
- Static tile serving → Tile manifest: serves manifest
- Weather data hooks → Static tile serving: fetches map data
- Expo app → CarPlay navigation: supports navigation
- Expo app → Watch and widget: shares radar data
- Storm watch workflow → Push notification service: sends notifications
