A real-time amateur radio dashboard for the modern operator.
OpenHamClock brings DX cluster spots, space weather, propagation predictions, POTA/SOTA/WWFF/WWBOTA activations, PSKReporter, satellite tracking, WSJT-X integration, direct rig control, an in-browser logbook, and a full emergency-communications mode into a single browser-based interface. Run it locally on a Raspberry Pi, on your desktop, in Docker, or just use the hosted site.
π Live Site: openhamclock.com
π§ Contact: Chris, K0CJH β chris@cjhlighting.com
β Support the Project: buymeacoffee.com/k0cjh β Running openhamclock.com comes with real hosting costs including network egress, memory, CPU, and the time spent maintaining and improving the project. There is absolutely no obligation to donate β OpenHamClock is and always will be free. But if you find it useful and want to chip in, your donations are greatly appreciated and go directly toward keeping the site running and funding future development.
π§ Get Involved: This is an open-source project and the amateur radio community is encouraged to dig into the code, fork it, and build the features you want to see. Whether it's a new panel, a data source integration, or a bug fix β PRs are welcome. See Contributing below.
π License: MIT β See LICENSE
| Guide | What's in it |
|---|---|
| Quick Start | Use the hosted site, or self-host on Docker, Linux/macOS, Raspberry Pi, Windows, Railway |
| User Manual | Every panel, map layer, keyboard shortcut, and setting explained |
| Docker Guide | Compose, Portainer, persistence, reverse proxies |
| Roadmap | Project history and what's coming |
| Contributing | Dev setup, code style, PR workflow |
| Testing | Unit test guide |
| Security Policy | Vulnerability disclosure |
| Architecture | Codebase map for contributors |
Release notes live in the app itself: click the version number in the header to open What's New.
- Interactive world map in three projections β flat (Mercator), azimuthal-equidistant centered on your QTH, and a full 3D globe with real satellite models β with a dozen basemap styles and ~28 toggleable overlay layers (gray line, aurora, MUF, D-RAP, lightning, satellites, RBN, WSPR, Maidenhead grid, CQ/ITU zones, aircraft, and more), most with single-key shortcuts.
- DX cluster spots from OpenHamClock's own cluster node (RBN + HamQTH + POTA/SOTA/WWFF + user spots, deduplicated), with band/mode/zone/watchlist filtering, worked-before and dupe badges from your log, click-to-tune, and click-to-listen via the nearest live KiwiSDR.
- Activations β live POTA, SOTA, WWFF, and WWBOTA activator panels with map markers.
- Native logbook β QSOs stored in your browser (IndexedDB), ADIF import/export, log-from-spot, and worked-before integration across all spot panels.
- Propagation β browser-side ITU-R P.533-14 (VOACAP-class) predictions via WebAssembly, point-to-point reliability charts, world heatmap, MUF map, band conditions, and ionosonde-corrected real-time data.
- Space weather β SFI/Kp/SSN with history, GOES X-ray flux, NOAA SWPC alerts, aurora forecast, solar imagery, lunar phase.
- Satellite tracking β SGP4 tracking of amateur satellites from CelesTrak/AMSAT/SatNOGS (optionally Space-Track), orbit tracks, footprints, pass info, and 3D models on the globe.
- Rig control β click any spot and your radio tunes, via the Rig Bridge (Yaesu, Kenwood, Icom, Elecraft, FlexRadio, flrig, rigctld, and more) with a cloud relay for hosted use.
- Digital modes β WSJT-X/JTDX decodes on the map (UDP or cloud relay), JS8Call/MSHV control, PSKReporter TX/RX reports in real time.
- Contest tools β contest calendar, N1MM+/DXLog QSOs plotted live on the map, band plan overlay on the rig display.
- EmComm layout β ARES/RACES dashboard with APRS (internet + RF via local TNC), net roster, point-to-point messaging, resource token aggregation, telemetry dashboards, NWS alerts, FEMA shelters and disaster declarations, Winlink gateways and Pat client.
- Meshtastic & MeshCom β mesh network nodes and messages on the map and in dockable panels.
- Works your way β dockable drag-anywhere layout, Classic (original HamClock style), and EmComm layouts; five themes including a custom theme editor; named profiles; 16 languages; PWA offline mode with cached data.
Just want to use it? Open openhamclock.com, set your callsign and grid, done.
Self-host with Docker:
docker run -d -p 3000:3000 --name openhamclock ghcr.io/accius/openhamclock:latestSelf-host from source (Node.js 22 LTS recommended):
git clone https://github.com/accius/openhamclock.git
cd openhamclock
npm ci
npm startOpen http://localhost:3000. A setup wizard walks you through callsign and grid on first run.
One-line installers for Linux/macOS (scripts/setup.sh), Raspberry Pi kiosk (scripts/setup-pi.sh), and Windows (scripts/setup-windows.ps1) β full commands and per-platform details in the Quick Start guide.
For development with hot reload:
# Terminal 1 β Backend (http://localhost:3001)
node server.js
# Terminal 2 β Frontend (hot reload on http://localhost:3000)
npm run dev| Platform | Method | Guide |
|---|---|---|
| Nothing (hosted) | openhamclock.com | Quick Start |
| Docker / Portainer | docker compose up -d or ghcr.io/accius/openhamclock:latest |
docs/DOCKER.md |
| Linux / macOS / FreeBSD | scripts/setup.sh (add --service for systemd on Linux) |
Quick Start |
| Raspberry Pi (3Bβ5) | scripts/setup-pi.sh (--kiosk for a dedicated display) |
Quick Start |
| Windows | scripts/setup-windows.ps1 |
Quick Start |
| Railway (cloud) | railway up or connect the GitHub repo |
Quick Start |
| Desktop app | npm run electron (experimental) |
β |
Hardware: the server side is light (~100β150 MB RAM); it's the browser rendering the map that works a machine. A Pi 4 (2 GB+) or Pi 5 makes a smooth kiosk; a Pi 3B+ is best as a headless server or with Low Memory Mode enabled in Settings. The 3D globe wants WebGL β without it the app falls back to the flat map automatically.
All configuration lives in .env (auto-created from .env.example on first run) β and almost everything can also be changed in the in-app Settings panel, which takes priority. The only two lines most people touch:
CALLSIGN=K0CJH
LOCATOR=EN10Files starting with a dot are hidden by default β
ls -lain a terminal,Ctrl+Hin a Linux file manager,Cmd+Shift+.in macOS Finder.
Settings priority: browser Settings panel (localStorage) β .env β built-in defaults. Your .env is never overwritten by updates. Self-hosted single-operator installs can set SETTINGS_SYNC=true to store UI settings on the server so every device gets the same setup.
The complete annotated list lives in .env.example. Highlights:
| Variable | Default | Description |
|---|---|---|
CALLSIGN |
N0CALL |
Your callsign β used for DX cluster login, PSKReporter queries, and "my spots" tracking |
LOCATOR |
FN31 |
Maidenhead grid (4 or 6 characters); LATITUDE/LONGITUDE override the derived coordinates |
PORT |
3001 (dev) |
Backend port. Containers run on 3000; in dev, Vite owns 3000 and proxies /api to 3001 |
HOST |
localhost |
Set 0.0.0.0 to allow other devices on your LAN |
THEME / LAYOUT |
dark / modern |
Startup theme (dark, light, legacy, retro) and layout (modern, classic) |
DISTUNITS / TEMPUNITS / PRESSUNITS |
imperial |
Distance, temperature, and pressure units (imperial or metric); UNITS is deprecated |
TIME_FORMAT |
12 |
12 or 24 hour clock |
SETTINGS_SYNC |
false |
Store all UI settings server-side (single-operator self-host only) |
WSJTX_ENABLED |
true |
WSJT-X/JTDX UDP listener (legacy name WSJTX_UDP_ENABLED still honored) |
WSJTX_UDP_PORT |
2237 |
Must match WSJT-X Settings β Reporting β UDP Server |
WSJTX_MULTICAST_ADDRESS |
(none) | Set when WSJT-X broadcasts to a multicast group (e.g. 224.0.0.1) |
WSJTX_RELAY_KEY |
(none) | Shared secret for the WSJT-X relay agent (cloud deployments only) |
AUTO_UPDATE_ENABLED |
false |
Periodic git self-update (legacy name AUTO_UPDATE still honored) |
AUTO_UPDATE_INTERVAL_MINUTES |
60 |
Update check interval (legacy name AUTO_UPDATE_INTERVAL still honored) |
DX_CLUSTER_SOURCE |
auto |
auto, proxy, hamqth, or dxspider; see the manual |
DX_CLUSTER_CALLSIGN |
CALLSIGN-56 |
Cluster login (use -57 for a second/staging instance) |
SPOT_RETENTION_MINUTES |
30 |
How long DX spots stay in the list (5β30) |
APRS_ENABLED |
false |
Read-only APRS-IS feed; filter with APRS_FILTER (e.g. r/40.12/-74.82/500) |
N1MM_UDP_ENABLED |
false |
Contest logger UDP listener on N1MM_UDP_PORT (12060) β see docs/N1MM-SETUP.md |
QRZ_USERNAME/QRZ_PASSWORD, HAMQTH_USERNAME/HAMQTH_PASSWORD |
(none) | Optional callbook credentials for better callsign lookups |
OPENWEATHER_API_KEY |
(none) | Only needed for the Cloud Layer map overlay (also set VITE_OPENWEATHER_API_KEY) |
API_WRITE_KEY |
(none) | Protects write endpoints β required for public/cloud deployments |
METRICS_AUTH_KEY |
(none) | Bearer-token auth for the Prometheus /metrics endpoint |
CELESTRAK_ENABLED / AMSAT_TLE_ENABLED / SATNOGS_TLE_ENABLED |
true |
Satellite element-set sources; SPACE_TRACK_USERNAME/_PASSWORD enable Space-Track as primary |
ITURHFPROP_URL |
(built-in) | External ITU-R P.533 service β only if self-hosting iturhfprop-service/ |
WINLINK_API_KEY |
(none) | Winlink gateway proxy (cloud deployments; local installs use the rig-bridge plugin instead) |
The backend exposes a JSON REST API under /api, heavily cached server-side to be kind to upstream services. Notable endpoints:
| Endpoint | Description |
|---|---|
GET /api/config, GET /api/version |
Station config and lightweight version check (drives the update toast) |
GET /api/health |
Live server dashboard β uptime, visitors, sessions, per-endpoint traffic (?format=json for raw data) |
GET /api/dxcluster/spots, /paths, /sources |
DX cluster spots, map paths, and available source backends |
POST /api/dxcluster/spot |
Submit a spot to the OHC cluster |
GET /api/pota/spots, /api/sota/spots, /api/wwff/spots |
Activator spots (1β2 min cache) |
GET /api/solar-indices, /api/noaa/xray, /api/noaa/aurora, /api/drap, /api/swpc/alerts |
Space weather feeds |
GET /api/n0nbh |
N0NBH band conditions |
GET /api/propagation, /heatmap, /mufmap |
Point-to-point prediction, world heatmap, MUF map |
GET /api/p533-data/:file |
ITU-R P.533 coefficient tables for the in-browser WASM engine |
GET /api/satellites/data |
Merged satellite element sets (CelesTrak / AMSAT / SatNOGS / Space-Track) |
GET /api/callsign/:call, /api/cty |
Callsign lookup and the AD1C cty.dat prefix database |
GET /api/rbn/spots, /api/wspr/heatmap |
Reverse Beacon Network spots and WSPR heatmap |
GET /api/pskreporter/stream/:id |
Live PSKReporter spots over SSE (server-side MQTT proxy) |
GET /api/wsjtx/decodes, POST /api/wsjtx/relay |
WSJT-X decodes and the cloud relay ingest |
GET /api/contests, /api/dxpeditions, /api/dxnews |
Contest calendar, DXpeditions, DX news |
GET/POST /api/contest/qsos |
N1MM/DXLog contest QSOs (UDP-fed, plus HTTP ingest) |
GET /api/aprs/stations, /messages, /telemetry, /net |
APRS stations, messaging, telemetry, net roster |
GET /api/emcomm/alerts, /shelters, /disasters |
NWS alerts, FEMA shelters and disaster declarations |
GET /api/winlink/gateways |
Winlink RMS gateways (needs WINLINK_API_KEY server-side) |
GET /api/websdr/receivers |
Nearest live KiwiSDR/WebSDR receivers for click-to-listen |
GET /api/aircraft, /api/atc/sectors |
ADS-B aircraft (adsb.lol) and ATC sector boundaries |
GET /metrics |
Prometheus metrics (optionally gated by METRICS_AUTH_KEY) |
Write endpoints (settings, rig, rotator, spot submission, etc.) are rate-limited and honor API_WRITE_KEY when set.
React 18 + Vite frontend, Express backend. The backend is an API proxy and data aggregator β external calls are cached server-side so any number of browsers add near-zero upstream load. Real-time data flows over SSE (DX cluster, PSKReporter, RBN), UDP (WSJT-X, N1MM), and a server-side MQTT proxy.
Companion services in this repo:
| Directory | Service |
|---|---|
rig-bridge/ |
Local rig control bridge β 20+ plugins (radios, digital modes, APRS TNC, rotator, Winlink) |
ohc-cluster/ |
OpenHamClock's own DX cluster node (telnet :7300 + HTTP), aggregating RBN, HamQTH, POTA/SOTA/WWFF, Parks n Peaks, DX Summit, and user spots |
dxspider-proxy/ |
Persistent telnet connection to the DX Spider network, served over HTTP |
iturhfprop-service/ |
ITU-R P.533-14 propagation engine as a REST API (self-host alternative) |
wasm-build/ |
Builds the P.533 engine to WebAssembly for in-browser predictions |
wsjtx-relay/ |
WSJT-X UDP β HTTPS relay for cloud-hosted instances |
fletcher/ |
TLE fetch egress proxy used by the hosted deployment |
watchtower/ |
Cloudflare Worker uptime probe |
Full codebase map: docs/ARCHITECTURE.md
- Hosted site β nothing to do; a toast appears when a new version deploys.
- Git installs β
./scripts/update.sh(Linux/macOS/Pi) or.\scripts\update.ps1(Windows), then restart. Local installs also get an UPDATE button in the header. Optional auto-update viaAUTO_UPDATE_ENABLED=true. - Docker β
docker compose pull && docker compose up -d. - Railway β push to the connected repo, or
railway up.
The update scripts back up .env, pull, rebuild, and restore .env β your configuration is never lost.
Do I need a license to use OpenHamClock? No β it's a receive-only dashboard. A callsign makes PSKReporter "my signal" views and cluster login meaningful, but anyone can watch spots and space weather.
Can multiple people use one server? Yes. Each browser keeps its own settings, filters, and DX target; the server cache means extra users add no upstream load. Shared-station operators can use Profiles (Settings β Profiles) to switch setups.
Why don't I see DX spots / PSK reports? Make sure your callsign is set. PSKReporter falls back from the live stream to HTTP automatically; check the panel footer for the active method. For clusters, check the server console and any custom DXSPIDER_PROXY_URL.
Emoji show as boxes on Linux/Pi? Install a color emoji font on the machine running the browser: sudo apt install fonts-noto-color-emoji, then restart the browser. The Pi setup script does this automatically.
Where's the .env file? In the repo root, hidden by the leading dot β ls -la shows it. Run npm start once and it's created from .env.example automatically.
More Q&A throughout the User Manual.
OpenHamClock exposes a Prometheus-compatible endpoint at /metrics (optionally protected with METRICS_AUTH_KEY as a bearer token) and a human-friendly health dashboard at /api/health.
OpenHamClock is built by the ham radio community β 40+ contributors and growing. Whether it's a bug fix, a new panel, a map layer plugin, or better docs, PRs are welcome.
git clone https://github.com/accius/openhamclock.git
cd openhamclock
git checkout Staging
npm ci
node server.js # Terminal 1 β Backend on :3001
npm run dev # Terminal 2 β Frontend on :3000Open pull requests against Staging, not main. Read CONTRIBUTING.md for the workflow, code style, and the documentation policy, and docs/ARCHITECTURE.md for the codebase map.
Community:
- GitHub Issues β bug reports and feature requests
- Facebook Group β discussion and help
- Reddit r/OpenHamClock β community discussion
- Settings β Community in the app β the contributors wall
- K0CJH (Chris Hetherington) β Creator and maintainer β chris@cjhlighting.com
- Elwood Downey, WB0OEW (SK) β Creator of the original HamClock that inspired this project. OpenHamClock is dedicated to his memory.
- Claude AI (Anthropic) β Accelerated development by assisting with bug fixes, code structure, and feature implementation
- Keith, G6NHU β DX Spider cluster operator at dxspider.co.uk
- NOAA Space Weather Prediction Center β Space weather data (SFI, Kp, SSN, X-ray flux, aurora, D-RAP)
- N0NBH (Paul Herrman) β Real-time band conditions data feed
- POTA / SOTA / WWFF / WWBOTA β Activator spot APIs
- PSKReporter β Digital mode reception report network
- Reverse Beacon Network β CW/RTTY/FT skimmer spots
- Open-Meteo β Free weather API
- Leaflet β Open-source mapping library
- CelesTrak Β· AMSAT Β· SatNOGS β Satellite orbital element data
- NASA β Imagery, EONET hazards data, and the ISS 3D model (NASA/VTAD)
- KC2G / GIRO β Ionospheric sounding data (acknowledgements)
- AD1C β cty.dat DXCC entity database
- NG3K β DXpedition listing
- DXNews.com / DX-World β DX news headlines
- WA7BNM β Contest calendar data
- adsb.lol β Community ADS-B aircraft feed
And thank you to every contributor β the full wall lives in the app under Settings β Community.
MIT License β See LICENSE file.
73 de K0CJH openhamclock.com Β· chris@cjhlighting.com