Red Alert Map

March 11, 2026 · View on GitHub

Real-time visualization of Israeli Pikud HaOref (Home Front Command) alerts on an interactive map with actual alert zone polygons.

Go React deck.gl Release Homebrew License

Red Alert Map Screenshot


What It Does

  • Polls the official Pikud HaOref API every 2 seconds for live rocket/missile alerts, hostile aircraft intrusions, earthquake warnings, and other hazards
  • Renders actual alert zone polygons (not just points) on a GPU-accelerated map using deck.gl
  • Broadcasts alerts in real-time via WebSocket to all connected browsers
  • Displays alert details in a Hebrew RTL sidebar with zone names, category, and shelter countdown times
  • Loads alert history on startup for immediate situational awareness
  • Single binary — Go backend with embedded frontend, zero runtime dependencies

How It Works

Pikud HaOref API ──(2s poll)──> Go Poller ──> In-Memory Store ──> WebSocket Broadcast
                                                                          |
                                                                          v
                                                  Browser ──> Zustand ──> deck.gl polygons
  1. The backend polls the Oref API every 2 seconds and processes incoming alerts
  2. Each alert zone name is matched against 1,450 pre-loaded polygons in memory
  3. New alerts are stored and broadcast via WebSocket to all connected clients
  4. The React frontend receives updates and renders pulsing colored polygons on a dark basemap
  5. Alert history from the Oref archive API is loaded on startup for immediate context

Tech Stack

LayerTechnology
BackendGo (single binary, zero dependencies)
StorageIn-memory (zones + alerts)
Real-timeWebSocket (gorilla/websocket)
Map enginedeck.gl 9 (GPU rendering) + MapLibre GL JS
FrontendReact 19 / TypeScript / Vite 6
StateZustand
StylingTailwind CSS 4 (RTL-ready)

Quick Start

Homebrew (macOS / Linux)

brew tap aviv4339/tap
brew install red-alert-map
red-alert-map

Open http://localhost:8765 in your browser.

From Source

# Prerequisites: Go 1.23+, Node.js 20+

# Build frontend + backend into a single binary
make build

# Run (auto-downloads zone data on first start)
./red-alert-map

Open http://localhost:8765 in your browser.

Development

# Using run.sh (recommended)
./run.sh start     # Start backend + frontend dev server
./run.sh stop      # Stop both
./run.sh restart   # Stop then start
./run.sh status    # Show running state + health info
./run.sh build     # Build frontend + Go binary
./run.sh logs      # Tail both log files

Or manually:

# Terminal 1: Go backend
go run .

# Terminal 2: Frontend dev server (hot reload)
cd frontend && npm install && npm run dev

Access via http://localhost:5173 (Vite proxies API calls to the Go backend).

Test Mode

If you're outside Israel or the Oref API is unreachable, use test mode to see simulated alerts:

RAM_TEST_MODE=true ./red-alert-map

API Endpoints

MethodPathDescription
GET/api/zonesAll 1,450 alert zones as GeoJSON FeatureCollection
GET/api/alerts/activeCurrently active alerts with zone polygons
GET/api/alerts/history?from=&to=Historical alerts within a time range
WS/api/wsReal-time alert stream (snapshot on connect, incremental updates)
GET/api/healthSystem status: zone count, alert count, last poll, WS connections

Configuration

Environment variables (all prefixed with RAM_):

VariableDefaultDescription
RAM_TEST_MODEfalseUse test fixtures instead of real API
RAM_PORT8765Server port
RAM_DATA_DIR~/.red-alert-mapDirectory for cached zone data
RAM_POLL_INTERVAL_SEC2.0Oref API polling interval in seconds
RAM_ALERT_DURATION_SEC300How long alerts remain "active" (seconds)

Alert Categories

CodeTypeColor
1Rockets & MissilesRed
2Hostile Aircraft IntrusionRed
3EarthquakeOrange
4Chemical HazardYellow
5TsunamiBlue
6Aircraft IntrusionPurple
13Terror InfiltrationDark Red
14Pre-alert WarningRed

Zone Data

Alert zone polygons are sourced from amitfin/oref_alert, which maintains accurate polygon boundaries that match the official Pikud HaOref zone names exactly. Zone data is auto-downloaded on first run and cached locally.

Zone names from the Oref API have a 100% match rate against the polygon dataset.

Project Structure

red-alert-map/
├── main.go                # Entry point, config, startup
├── store.go               # In-memory zone + alert store
├── seed.go                # Download zone polygons + metadata
├── processor.go           # Alert parsing + zone matching
├── poller.go              # Oref API polling loop
├── hub.go                 # WebSocket connection hub
├── handlers.go            # HTTP/WS route handlers
├── testdata.go            # Test mode fixtures
├── run.sh                 # App management script (start/stop/restart/status/build/logs)
├── Makefile               # Build frontend + Go binary
├── .goreleaser.yaml       # Cross-platform release config
├── go.mod / go.sum
├── frontend/
│   ├── package.json
│   ├── vite.config.ts
│   └── src/
│       ├── App.tsx                  # Root component
│       ├── components/
│       │   ├── MapView.tsx          # deck.gl + MapLibre map
│       │   ├── AlertPanel.tsx       # RTL alert sidebar
│       │   ├── StatsPanel.tsx       # Collapsible stats panel
│       │   ├── stats/              # Stats sub-components
│       │   ├── TimeSlider.tsx       # History time range
│       │   └── Header.tsx           # Status bar
│       ├── hooks/
│       │   ├── useWebSocket.ts      # WS with auto-reconnect
│       │   ├── useAlerts.ts         # Zustand store
│       │   └── useStats.ts         # Stats aggregation hook
│       ├── layers/
│       │   ├── alertPolygonLayer.ts
│       │   └── zoneBaseLayer.ts
│       └── lib/
│           ├── types.ts
│           └── constants.ts
└── docs/
    └── screenshot.png

Acknowledgments

License

MIT