Disclaimer: This is an independent hobby project. It is not affiliated with, endorsed by or supported by the N1MM Logger+ team or anyone else. All product names belong to their owners and are used only to describe compatibility.
This software was developed with AI (Claude, by Anthropic) and has only been tested at one station. Use it at your own risk. It comes with no warranty of any kind. Licensed under GPL-3.0.
A live dashboard for ham radio contests. It listens for the UDP broadcasts N1MM Logger+ sends and shows score, rates, operators, radios, band and mode breakdowns, and a map of every contact with great-circle lines from your station. Anyone on your network can watch it in a web browser: a TV in the shack, other operators, or guests at Field Day.
It is a single small program. No Node-RED, no Raspberry Pi, no database to install. It can run on the logging computer itself, on any other computer on the network, or as a Docker container.
- Score, QSOs, mults and points. The score is the one N1MM calculates and broadcasts, so it is always right for the contest you're in. If N1MM isn't sending score reports, the dashboard shows an estimate (points × mults) and says so.
- Rates: last hour, last 10 minutes (as an hourly rate), and the best 60 minutes so far.
- Map of every contact, coloured by band, with lines to the 25 most recent. Contacts are placed by grid square when the exchange has one, by state, province or ARRL section in domestic contests, and otherwise by country (from the callsign prefix, using the same country file loggers use). No callsign lookups or internet services are needed for this.
- The map background is a free one that needs no account or API key: Esri's grey map (default) or OpenStreetMap, chosen on the Settings page. The dashboard fetches map pieces itself and saves them, so a map that's been viewed once keeps working without internet.
- Radios: frequency, mode, operator, run or search-and-pounce, and a red TX marker while transmitting, for every radio N1MM reports.
- Contacts over time by band, bands and modes table, operators league table, top countries, and an hour by hour rate sheet.
- A full-screen map page (the Map button), made for a TV or streaming.
Race this year's effort against the same contest last year (or any earlier year you have logged). The two are lined up by time into the contest, so you can see at a glance whether you're ahead or behind where you were at this point, by QSOs or by score. A tile at the top keeps the running difference in view.
Click any operator for their own page, or use Compare operators to see everyone side by side, sortable, with the best in each column highlighted.
- Run rate and S&P rate count only the time spent doing each, and leave out breaks over 10 minutes.
- Rate over time: a rolling rate line (over the last 15, 30 or 60 minutes) for each operator, split into run and S&P on their own page. A dip shows when someone slows down; a gap means they were off the air.
- Max rates like N1MM's rate reports: best 10 and best 100 QSOs in a row, best 15, 30 and 60 minutes, longest run and fastest run of 20 or more contacts, plus a list of each operator's biggest runs.
- Across contests: how each operator's run rate, S&P rate, best hour and so on have changed from one contest to the next, so you can see who is improving. Pick one contest (for example only CQ WW SSB) so like is compared with like.
- Every panel has a ⤢ button that makes it fill the screen (Esc to go back), and clicking any tile at the top shows just that number, huge. Adding
?full=ghostor?full=tile-scoreto the address opens a page that way. - Edit layout lets you drag panels around, make them wider or narrower, taller or shorter, hide the ones you don't want, and hide individual tiles. The layout is kept in that browser.
- Save as named view stores a layout on the dashboard computer under a name such as "TV". Any screen can then pick it from the Layout list, or open
http://<address>:8060/?view=TV. - Open for a public screen opens the layout with no buttons (
&kiosk=1), so nobody can change it from a TV in the club room. Press F11 in the browser for true full screen.
- Download
contest-dashboard-windows.zipfrom the latest release on the Releases page, right-click it, choose Extract All, and put the folder somewhere permanent, for exampleC:\Ham\ContestDashboard\. - Double-click
contest-dashboard.exe. Windows may say "Windows protected your PC": click More info, then Run anyway. (The file isn't code-signed yet.) - When Windows Firewall asks, tick Private networks and click Allow. This lets other computers watch the dashboard and lets N1MM on other computers reach it.
- Your web browser opens the dashboard at http://127.0.0.1:8060. There is no program window. Double-click the program again any time to reopen the page. To stop it, use Stop the dashboard program at the bottom of the Settings page.
To try it before a contest, open Settings and click Start the demo. It makes up a two-radio contest with a few hours of history and new contacts at a realistic pace, plus the same contest in the two previous years so the ghost runner and the across-contests charts have something to show. Delete the demo contests from the Contests list when you're done.
In N1MM+ open Config, then Configure Ports, Mode Control, Winkey, etc., then the Broadcast Data tab.
- Tick Radio, Contacts and Score.
- In the address box next to each, type the address of the computer running the dashboard and a port, for example
127.0.0.1:12060when the dashboard runs on the same computer, or192.168.1.50:12060for another computer. (Settings shows this computer's address.) You can list more than one destination separated by spaces if another program also needs the data. - If the Score tile keeps saying "estimate" instead of "from N1MM" during a contest, check that Score is ticked and also look at N1MM's score reporting settings. The dashboard itself never sends anything to the internet.
In a multi-computer N1MM network, set this up on every logging computer.
The Settings page shows whether packets are arriving and from where. The dashboard listens on ports 12060, 12061 and 12062 by default and works out what each packet is from its contents, so it doesn't matter which of those ports each type is sent to.
Export it from N1MM with File, Export to ADIF, then use Import an ADIF log on the Settings page. Pick it from the contest list at the top of the dashboard.
Docker runs programs in a sealed box called a container, which is handy on a home server, a NAS or a Raspberry Pi that's always on. GitHub builds the container automatically and stores it with the code at ghcr.io/jsttylr/contest-dashboard.
On a Linux machine with Docker installed:
docker run -d --name contest-dashboard --restart unless-stopped \
--network host \
-v contest-dashboard-data:/data \
ghcr.io/jsttylr/contest-dashboard:latestThen open http://<that machine's address>:8060/ from any browser on your network, and point N1MM at that same address on port 12060.
--network hostlets the container hear UDP broadcasts. If you'd rather not use it, replace it with-p 8060:8060 -p 12060-12062:12060-12062/udp; that works as long as N1MM sends straight to the machine's address rather than to a broadcast address.-v contest-dashboard-data:/datakeeps settings and contacts when the container is updated.- To update:
docker pull ghcr.io/jsttylr/contest-dashboard:latest, then remove and re-run the container. Your data stays in the volume. - Inside Docker, settings can be changed from any computer on your network (normally only the computer running the dashboard can change them).
- Docker Desktop on Windows can't hear UDP broadcasts well, so on Windows the plain program above is the easier choice.
If you use Docker Compose, the repo includes a ready-made docker-compose.yml: copy it to your Docker host and run docker compose up -d.
The image tags are latest (newest release), a version number such as 0.1.0, and main (newest build, may be unfinished).
There's a ready-made Unraid template, with the web page link, icon and appdata folder filled in.
- Open the Unraid Terminal (the
>_icon at the top right) and run:wget -O /boot/config/plugins/dockerMan/templates-user/my-contest-dashboard.xml \ https://raw.githubusercontent.com/jsttylr/contest-dashboard/main/unraid/contest-dashboard.xml
- On the Docker tab click Add Container, then pick contest-dashboard from the Template list (under User templates).
- Check the settings and click Apply. Settings and contacts are kept in
/mnt/user/appdata/contest-dashboard, so they're in your appdata backups and survive updates.
Updates come from Check for Updates on the Docker tab. To switch an existing container to the template, remove the container (not its appdata folder) and add it again from the template; as long as the appdata path is the same, nothing is lost.
Download the new zip and run the new contest-dashboard.exe. If an older version is still running, the new one stops it and takes over; your settings and contacts are kept.
Settings (config.json), the contact log (contacts.jsonl) and a log file are kept in:
- Windows:
%AppData%\contest-dashboard\ - Mac:
~/Library/Application Support/contest-dashboard/ - Linux:
~/.config/contest-dashboard/ - Docker: the
/datavolume
The contact log is plain text, one contact per line, written as each contact arrives, so a crash or power cut loses nothing.
Install Go 1.24 or newer, then go build . in this folder. go test ./... runs the tests.
- Country data: AD1C's country files, via
@ham2k/lib-country-files(MIT). - Map: Leaflet (BSD-2-Clause), with the outline from world-atlas / Natural Earth (ISC, public domain). Online map tiles from Esri and OpenStreetMap contributors.
- Charts: Chart.js (MIT).
- Inspired by the Node-RED Contesting Dashboard by Kyle Krieg, AA0Z. Many of the ideas here, and the idea of a live contest dashboard fed by N1MM, come from his work. Thank you, Kyle.
GPL-3.0. See LICENSE.





