ØSIL Trim
Trim-post app for a local sports club. Catalogue, map, offline PWA and visit log, built on the club's request and in use by its members.
→ 30 registered members, 164 logged visits in the first season (May–Oct 2026).
Øvre Surnadal Idrettslag (ØSIL) runs a trim: a set of fixed hiking goals in the woods and mountains around Øvre Surnadal, each with a trim box where visitors mark that they have been there. What people needed to know about the posts was spread across the trim group’s Facebook posts, and visits were counted the traditional way, with pen and paper.
The club asked for an app. ØSIL Trim is what they got: built on their request as voluntary work, live at osiltrim.solheimsolutions.no, and used by the club’s members on the trail.
What it does
- Catalogue and map. Every post has photos, a description, elevation, distance, season, and notes on parking and where to start. Search and filter by difficulty and season, or browse the posts on Kartverket’s topographic map. One tap opens a post in Google Maps or the phone’s own map app.
- Visit log. Members register with their name and a password and mark a visit with a date. It is an honour system, like the paper trim book. “I’m here now” is an optional GPS check-in that accepts the visit within 300 metres of the post.
- My collection. Your visits, your progress, and the nearest post you have not been to yet. Showing your name on the shared board is opt-in; private is the default.
- Prize draw. The club draws prizes among everyone who has logged visits. An admin page lists who is in the draw; the draw itself stays manual.
- Editing in the field. Club editors add and update posts from their phones, capturing GPS position and photos at the post itself.
Built for poor coverage
Mobile coverage in the Nordmøre mountains is poor, and that decided the architecture. ØSIL Trim is a progressive web app that installs to the home screen. The service worker caches map tiles and the posts you have opened, and a download option fetches the rest before you leave. A visit logged without signal waits in a queue on the phone and is sent when the connection returns.
The first version used the browser’s Background Sync API for that queue. It produced duplicate visits and is not available on iOS, so a plain local queue replaced it.
┌─[ 00 ON THE TRAIL ]──────────────────────────────────┐ │ > "I've been here" no signal │ └─────────────────────────┬────────────────────────────┘ ▼ ┌─[ 01 PHONE ]─────────────────────────────────────────┐ │ │ │ save visit ──> local queue ──> wait │ │ │ └─────────────────────────┬────────────────────────────┘ ▼ ┌─[ 02 BACK IN COVERAGE ]──────────────────────────────┐ │ │ │ queue ──> API ──> collection · board · prize draw │ │ │ └──────────────────────────────────────────────────────┘
Kept small on purpose
The backend is one small Flask app that stores its data as JSON files on disk, written atomically under a lock. There is no database server. The spec names the trigger for adding one: a user count well beyond the hundred or so that JSON files handle comfortably. Until then, one fewer moving part means one fewer thing to break for a club run by volunteers.
The frontend is React with Vite, Leaflet for the map, and Workbox for the service worker. It runs on Solheim Solutions’ own Linux server, and a push to the repository deploys it.
Live the same day, shaped by use since
The first commit landed before noon. By mid-afternoon the React app was deployed with the map and editor login, and by evening a first visit tally was in. Most of the work since has come from real use. The first fixes came four days in, after the editors had used the editing flow on real posts.
In September 2026 the club’s board asked for children to be part of the prize draw, in case the paper trim books are phased out. “My family” now lets a member log visits for children or a partner who have no account of their own. Family members never appear on the public board; only the member and the club’s admins can see them.
Stack
- React 18 and Vite, Leaflet with Kartverket topographic tiles
- PWA with Workbox: offline map tiles and posts, a local visit queue
- Flask and gunicorn, bcrypt password hashing, JSON files instead of a database
- Self-hosted on Linux behind nginx, with deploy on push
Status: in production since April 2026. On 9 October 2026 the visit log held 30 registered members (club admin accounts not counted) and 164 logged visits since 1 May, across all 12 posts. An honour-system tally, so these are visits people chose to log, not a count of everyone on the trail.