Glucava
After a Strava activity ends, Glucava reads your glucose data (Dexcom Share, FreeStyle Libre, Nightscout) and writes time in range, min, max, average and a sparkline into the activity description, optionally with a glucose and heart rate chart photo. One Go binary with a PocketBase backend and a server-rendered web UI.






Strava's API is paywalled, and I wanted my blood glucose next to my runs and rides without paying for it. Glucava is a free, self-hosted answer: when an activity finishes it takes the glucose readings from the activity window and writes a short block into the description, for example "TIR 92% | min 78 | max 164 | avg 112 mg/dL" plus a sparkline. It replaces only its own block and leaves the rest of the text alone. Since there is no API access, the write goes through a headless Chrome session that drives Strava's edit page with the user's own session. To get that session, a remote sign-in browser shows up inside the web UI: you log in to Strava as usual, Glucava keeps only the cookies, encrypted, and never sees the password. Glucose comes from Dexcom Share, FreeStyle Libre (via LibreLinkUp) or Nightscout, and a Tasker, Shortcuts or HTTP trigger endpoint can start a check the moment the activity ends. It is one Go binary: PocketBase for database, auth and admin, gomponents and Datastar for the server-rendered UI, plus an optional chart photo (glucose, heart rate and elevation panels) drawn by Glucava itself. It also has ntfy, webhook and email notifications, an edit-page canary that notices when Strava changes its markup, weekly summaries, encrypted secrets with key rotation, and a demo mode with fake data ("make mock"). Everything is AGPL-3.0 and Docker-ready. It is not a medical device and is documented as such.
Architecture
graph TD Src["Dexcom Share · LibreLinkUp · Nightscout"] -->|poll| Ingest["glucose ingest"] Trigger["Tasker / Shortcuts
POST /api/trigger"] --> Poll["activity poller"] Poll -->|new activity| Stats["time in range · min · max · avg"] Ingest --> Stats Stats --> Render["description block + chart photo"] Render -->|headless Chrome, your session| Strava["Strava edit page"] Stats --> PB[("PocketBase")] PB --> UI["web UI (gomponents + Datastar)"] Stats --> Notify["ntfy · webhook · email"]