A free Garmin Connect IQ widget that tracks caffeine intake and models its decay using the established 5.7-hour pharmacokinetic half-life, so you always know how much caffeine is still active — and when you'll be safe to sleep.
- Glance view — current caffeine level and time-to-sleep-safe at a glance in the widget loop
- Summary screen — large mg display, progress bar toward daily limit, intake vs. limit, time-to-safe
- Timeline graph — 12-hour window (4h past + 8h future) with dose markers, area fill, bedtime marker, and a prominent NOW indicator
- Today's drinks — interactive log with cursor selection. SELECT to open an action menu: edit time by preset offset (−15 min through −3 hours, or +15/+30 min for fine-tuning) or delete a mis-tapped entry instantly
- History view — 14-day caffeine bar chart with daily-limit reference line. Pick any day to see the drinks logged that day (per-drink detail for the last 14 days, daily-total-only for older days, going back 90 days)
- 12 drink presets — Espresso, Americano, Drip Coffee (S/L), Latte, Green Tea, Black Tea, Red Bull, Monster, Cola, Dark Chocolate, Pre-Workout. Add, rename, and remove from the phone companion.
- Daily limit alerts — gentle vibration at 80%, stronger alert at 100%
- Safe-to-sleep notification — fires when caffeine drops below 50 mg within 2 hours of your bedtime
- Phone companion — manage presets, adjust limits and bedtime, view history and trends inside the Garmin Connect app
- Two-way sync — drinks stream to the phone (full-day replace-day resync so edits and deletes stay consistent); settings and preset edits stream back to the watch
- 100% free, no ads, no tracking, no accounts — all data stays on your watch and phone
From the Connect IQ Store Install directly on your watch via apps.garmin.com/en-US/apps/7f81c51f-3f4c-486b-b38f-444ac962df47 or search "HalfLife Caffeine" in the Connect IQ store.
Sideload the pre-built release
- Download the latest
.iqor.prgfrom the Releases page - Connect your watch via USB
- Copy the
.prgtoGARMIN/APPS/ - Disconnect and find the widget in your widget loop
42 watches across these families:
- Vivoactive 4, 5, 6
- Venu 2, 2 Plus, 2s, 3, 3s · Venu Sq 2, 2m
- Forerunner 165 (+ music), 255 (+ music, s, sm), 265, 265s, 955, 965
- Fenix 6, 6s, 6 Pro, 6x Pro, 7, 7s, 7x · Fenix 7 Pro family (regular, s, x, no-WiFi, x no-WiFi) · Fenix 8 (43mm, 47mm, Solar 47mm/51mm, Pro 47mm) · Fenix E
- Epix 2 · Epix 2 Pro (42mm, 47mm, 51mm)
Requires Connect IQ API 3.2+ (for glance views). See manifest.xml for the authoritative product list.
- Connect IQ SDK 9.1+
- VS Code with the Monkey C extension
- A developer key (
openssl genrsa -out private_key.pem 4096 && openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt)
VS Code: Run → Run App (select target device from the list).
CLI:
monkeyc -f monkey.jungle -d vivoactive5_sim -y path/to/developer_key -o bin/CoffeTracker.prg -wmonkeyc -e -f monkey.jungle -y path/to/developer_key -o bin/HalfLifeCaffeine.iq(:test) annotated functions in test/ — execute via Run → Run Tests in VS Code.
source/ Monkey C source
├── HalfLifeCaffeineApp.mc Entry point, manager wiring
├── CaffeineModel.mc Decay math and projections
├── StorageManager.mc Persistence layer (14-day doses + 90-day daily totals)
├── DrinkPresets.mc Preset list (defaults + phone sync)
├── AlertManager.mc Daily limit and sleep notifications
├── SyncManager.mc Phone companion sync (replace-day mode)
├── Util.mc Formatting helpers
├── Colors.mc Palette constants
├── GlanceView.mc At-a-glance view
├── SummaryView.mc Main screen
├── TimelineView.mc Graph
├── LogView.mc Today's drinks (cursor + select to edit/delete)
├── HistoryView.mc 14-day chart + day list
├── DayDetailView.mc Per-day drill-down
├── EditDrinkMenuDelegate.mc Edit / delete action menu for a logged drink
├── EditTimeMenuDelegate.mc Preset time-offset picker
└── ...Delegate.mc Other input handlers
resources/
├── drawables/ Launcher icon (SVG) + drawables.xml
├── properties.xml User setting defaults
├── settings.xml Garmin Connect settings UI
└── strings.xml Localizable strings
companion/
└── settings/ HTML/JS phone companion (runs inside Garmin Connect)
test/ Monkey C unit tests
docs/
├── superpowers/ Design spec and implementation plan
└── store-listing.md Draft store copy
See CLAUDE.md for deeper architecture notes (glance vs. full-view process split, persistence conventions, message protocol, domain invariants).
- Half-life: 5.7 hours (
CaffeineModel.HALF_LIFE_SECONDS = 20520) - Formula:
current_mg = dose_mg × 0.5^(elapsed_seconds / 20520) - Sleep-safe threshold: 50 mg
- Default daily limit: 400 mg (FDA guideline; user-configurable)
- Retention: 14 days of per-dose detail + 90 days of daily totals (rolled up overnight, drives the History bar chart)
Issues and PRs welcome. If you're adding a feature, keep in mind:
- New classes reachable from the glance view need the
(:glance)annotation - Dictionary values do not round-trip through
Application.Storage; serialize to arrays (seeStorageManager.saveDoses) - Follow the existing manager pattern — add managers in
HalfLifeCaffeineApp.initializeManagers()and persist inonStopif their state is in-memory only
Built with the Connect IQ SDK. Caffeine half-life figure of 5.7 hours drawn from published pharmacokinetic studies of healthy adults.





