The idea
A progressive-web-app gym logger that works offline and generates your next session's targets automatically. You log each exercise, set, rep count, and weight between sets on your phone. After saving a session the app computes what to lift next time: same exercises, same rep scheme, weight stepped up by whatever increment you configured per exercise. The entire history lives in IndexedDB on your device. No account, no monthly fee, no login screen.
The core loop is fast by design: open the app, see last session's numbers in a reference column, tap in today's numbers alongside them, save. Thirty seconds per exercise.
Why build this
The dedicated logging apps in the App Store split into two camps: subscription-gated (Strong at $10/month, Hevy at $8/month, JEFIT at $7/month) or bloated with social features, coach marketplaces, and upsell modals. A person following a simple linear progression — 3×5 squat twice a week, add 2.5 kg each session — does not need a social feed. They need a fast offline log and a number to chase.
Progressive overload is the foundational mechanic of strength training, and no free tool implements the weight suggestion automatically. The proposal "last session you squatted 3×5 at 90 kg — today's target is 3×5 at 92.5 kg" is trivially computed but no existing free app surfaces it as a first-class feature. That suggestion, delivered without friction at the start of each session, is the entire pitch.
A PWA is the right deployment target. It installs from the browser on iOS and Android without app store review, works offline in a gym with poor signal, and requires no backend to function. The distribution cost is a static host.
Stack sketch
- Framework: React with Vite; installable as a PWA via
vite-plugin-pwawith a Workbox-generated service worker that caches all assets on first install - Local storage: Dexie.js (IndexedDB wrapper) — one table for the exercise library (name, default step increment, unit), one for sessions (date, an array of set entries keyed by exercise, session notes)
- Progressive overload engine: a pure function that reads the most recent session's entries for a given exercise and returns a target: same sets and reps, weight incremented by the configured step; if the last session recorded fewer reps than the target on any set, the weight target is held flat
- UI: Tailwind CSS with large tap targets designed for one-handed use with sweaty fingers; dark mode as the default
- Charts: Recharts rendering a line chart of estimated one-rep max (Epley formula:
weight × (1 + reps/30)) over time per exercise - Hosting: Cloudflare Pages — static bundle, edge-cached globally, zero ongoing cost
Scope for v1
- Predefined exercise library covering the main compound lifts: squat, bench press, deadlift, overhead press, barbell row, pull-up, dip; plus free-form custom exercise creation
- Per-exercise configurable weight-step increment (default 2.5 kg for upper body, 5 kg for lower body) and rep target
- Log each set: reps completed, weight used, optional RPE 1–10
- While logging an exercise, the previous session's sets appear as a static reference column beside the current entry fields
- "Next session" target view generated automatically on save: one table showing every exercise and its target weight for next time
- Per-exercise history chart (e1RM over time) and a raw set log
- PWA install prompt on first visit; offline-capable after install
- Export all data to a single JSON file
- Deliberately out of v1: cloud sync, social features, coach-designed program templates beyond the simple linear increment, video exercise demonstrations, rest timers, built-in plate calculator
Where it could go
A plate-loading calculator overlaid on each set entry is the most requested quality-of-life feature in every lifting app forum. You configure your gym's plate inventory once (four 20 kg, four 10 kg, four 5 kg, and so on) and the app renders exactly which plates to load per side of the bar for each target weight. The calculation is trivial — a greedy bin-packing pass over available denominations — and the friction it eliminates (doing this arithmetic in your head while fatigued) is real enough that it would make the app worth installing on that feature alone.
The second expansion is optional sync via a self-hosted backend. The data model is append-only — sessions are immutable JSON objects once saved — so a lightweight FastAPI endpoint backed by SQLite is all it takes to keep a phone and a tablet in sync. A QR-code-based device pairing flow (the server generates a one-time token, the new device scans to claim it) keeps setup at the level of complexity the target audience is comfortable with and avoids requiring a user account.
Watch out for
The Epley formula overstates one-rep max at low rep counts (below three reps) and becomes unreliable above ten reps per set. Present the e1RM chart as a relative trend indicator, not a precise performance number — label the y-axis "estimated 1RM (Epley)" and add a tooltip explaining that the value is meaningful for comparing sessions over time, not for setting competition openers. Showing a spuriously precise number without that caveat will earn immediate distrust from anyone who knows how the formula behaves.