QSOlog: a logbook for radio amateurs that needs no server
Our open-source project QSOlog logs radio contacts entirely in the browser: offline-first PWA, data in IndexedDB, ADIF export. What the project shows about web applications without a backend.
Radio amateurs document every contact - a QSO in ham radio jargon - in a logbook: the other station's callsign, frequency, mode, signal report, time in UTC. Traditionally that was a notebook on the station desk; today it is usually software. With QSOlog we built such a logbook as an open-source project - and made an architectural decision that makes it interesting beyond the hobby: there is no server.
No backend is a feature
QSOlog runs entirely in the browser. All QSOs live in IndexedDB, accessed through Dexie.js. There is no account, no sign-in, no database on a server and no transfer of log data to third parties. That has three pleasant consequences:
- Privacy by architecture: Data that never leaves the device does not need to be secured, encrypted or covered by a data processing agreement.
- Operations without operating costs: The application is a static website. GitHub Pages is all the hosting it needs; there is nothing to patch, scale or monitor.
- No outage risk: A service that does not exist cannot be shut down. The logbook keeps working even if the project were no longer maintained one day.
The price is discipline elsewhere: the data lives in the browser profile, so the export features have to be first class - more on that below.
Offline is the default, not the exception
Ham radio often happens where mobile coverage is weak: on summits, in a field day tent, on holiday. A logbook that requires an internet connection would be optimised for the wrong place. QSOlog is therefore built as a Progressive Web App: after the first load, a service worker (via vite-plugin-pwa) takes over delivery, the app can be installed on desktop and smartphone, and it starts without a network.
It is the same offline discipline we recommend for internal line-of-business applications used in the field: write locally first, the network is optional. Only the optional callsign lookups via QRZ.com or HamQTH need a connection - and they are deliberately designed as an extra, not a requirement.
The data belongs to the user
When there is no server backing up the data, the export has to be first class. QSOlog speaks ADIF 3.1.4, the established interchange format of the amateur radio world, plus CSV and JSON. The import validates the data and detects duplicates, so existing logs from other software can be migrated safely. For paper, there are PDF reports in A4 landscape with summary statistics.
That is the same stance we take in client projects: an application is only finished when you can leave it again. Standard formats in, standard formats out - no lock-in.
Domain logic entirely in the frontend
Without a backend, the whole domain moves into the frontend, and amateur radio has plenty of it:
- Maidenhead locator: From two grid square entries, QSOlog calculates the distance and bearing of the contact.
- Automatic band detection: The entered frequency is mapped to the matching amateur band, from 160m to 23cm per IARU Region 1.
- RST per mode: The signal report follows the standard appropriate to the operating mode.
- Statistics and map: Chart.js visualises band and mode distribution, activity streaks and DXCC entities; Leaflet plots all contacts on a map with marker clustering, dark mode included.
Technically, the stack is Vue 3 with TypeScript and Vite, Pinia for state, and Tailwind CSS with Headless UI for the interface. Multiple operator profiles and a German-English interface round it off.
What the project shows
QSOlog is a side project born from genuine personal need - and at the same time an honest test case for a point we often make: for many applications, the installable web app is the more direct route than an app store presence, and not every application needs a server. The code is MIT-licensed on GitHub; parts of it were written with the help of AI coding tools and reviewed by humans - the repository states this transparently. If you are a ham, or simply want to see a cleanly built offline-first PWA: try it, fork it, issues welcome.