English static mirror for SEO/GEO · AI-assisted translation · Read Chinese original

openGym: The Engineering Density of a Self-Hosted Fitness Tracker

Forum topic · ✨步子哥 · 2026-10-07

Summary

openGym is a self-hosted, open-source fitness tracker (JavaScript) that gained 1,494 stars in a day, positioning itself as a data-sovereignty alternative to SaaS apps like Hevy and Strong. A single docker compose command deploys it, with no accounts, subscriptions, ads, or telemetry, and full JSON export. It ships a local library of 1,324 exercises with animations and body-map browsing, fully offline-capable. Notable engineering choices include field-level merge for concurrent multi-device edits (a simplified CRDT approach), passkey authentication via WebAuthn with no password or email server required, and a PWA architecture avoiding app-store review. Beyond logging, it encodes coaching logic: linear progression, Greyskull LP, double progression, and time progression algorithms, plus structural-balance ratios based on Poliquin and Thibaudeau theory that flag imbalances like excessive bench-to-row strength gaps. A three-mode muscle map shows volume, recovery, and detrained muscle groups. It imports from FitNotes, Strong, Hevy, and Apple Health, and strips GPS location from progress photos on-device before upload. The post argues openGym rebuilds a SaaS-captured app category with genuine engineering integrity.

openGym: The Engineering Density of a Self-Hosted Fitness Tracker

> Project: DuarteSantos8/openGym · JavaScript · 1494 stars/day

When "Your Data" Actually Belongs to You

Imagine logging three years of workouts in Hevy, only to have the free tier capped at 50 entries. You export a CSV and discover the format is Hevy-proprietary — field names like exercise_id_1234 instead of bench_press — and importing into Strong fails. Three years of training data, locked inside one app.

This isn't an edge case. The business model of fitness apps is data lock-in — your training history is leverage; pay up or lose it. openGym's response is blunt:

> No account on someone else's server, no subscription, no ads, no telemetry. One docker compose up and it's running.

A single docker compose up, data on your own hard drive, export is a JSON file. This isn't just a fitness app — it's an engineering statement about data sovereignty.

1,324 Exercises: Not Data, Infrastructure

openGym ships 1,324 exercises, each with animated demonstrations, browsable by muscle group on a body map and filterable by available equipment.

The number itself isn't remarkable — ExRx.net has more. What's remarkable is that the library is part of the app, not an API call. Most fitness apps store their exercise databases in the cloud. openGym's is bundled locally and works offline.

That means: 1. Full functionality in gyms without WiFi (very common) 2. The library can be forked and modified — don't like an animation? Replace it

Field-Level Merge for Concurrent Edits

This is openGym's most interesting engineering detail.

You log a workout on your phone while reviewing last week's records on your laptop. Both devices edit the same workout simultaneously. Most apps do "last-write-wins" — one device's edits overwrite the other.

openGym does field-level merging:

> Two devices editing at once merge field by field instead of overwriting each other.

If you change the weight on your phone and the reps on your computer, both changes survive. This requires version tracking per field and per-field conflict resolution — a simplified CRDT (Conflict-free Replicated Data Type) approach. Notion, Figma, and Linear do similar things. openGym applies it to a fitness tracker — engineering standards an order of magnitude above the problem's scale.

Passkey Authentication: A World Without Passwords

openGym uses passkey authentication — Face ID / Touch ID / fingerprint. No passwords, no "forgot password" emails, no SMS codes.

Password sign-in can be enabled per instance (PASSWORD_SIGNIN=true), but is off by default. New device pairing uses one-time codes or QR codes.

Passkeys have better UX — nothing to remember, nothing to leak — but are harder to implement: WebAuthn API, hardware support, cross-device sync. openGym chose the harder, better path.

For self-hosted apps there's a bonus: no mail server needed. Password resets require email, and self-hosted email servers are a nightmare. Passkeys bypass that entirely.

Progression Algorithms: Not Just Logging, Coaching

openGym implements several strength-training progression schemes:

  • Linear progression: add fixed weight each session. For beginners.
  • Greyskull LP: deload on failure, add weight on success. For intermediates.
  • Double progression: add reps within a range, then add weight. For intermediate/advanced lifters.
  • Time progression: for isometric holds (planks, etc.).
  • Every progression rule explains "why this number" — target weights are computed from last week's performance, not arbitrary. Failures don't trigger increases; plateaus trigger deload weeks.

    This is coaching logic encoded in software. Most apps just record. openGym says: "you benched 80kg×5 last week, so this week is 82.5kg×5 — if you can't get 5 reps, back to 80kg."

    Muscle Map: Three Modes

    1. Volume mode: where your training volume went — which muscle groups you trained most 2. Recovery mode: what's still recovering — recently trained groups marked as "recovering" 3. Detrained mode: what's been neglected — groups untrained for a long time marked "detrained"

    Three modes answer three different questions: what you trained (past), what you can train now (present), what you should train (future). Most apps only answer the first. Detrained mode is especially valuable — it flags neglected muscle groups and prevents imbalances.

    Import/Export: Good Faith in Data Migration

    openGym imports from FitNotes, Strong, and Hevy (CSV or API key), plus body-weight data from Apple Health. Export is a single JSON file containing all workouts, weight data, and progress photos.

    The existence of import is itself a statement: your data is yours, not the app's. Most apps make importing easy (for acquisition) and exporting hard (for retention). openGym makes both easy.

    Progress photos deserve note:

    > Location data is stripped on the device before upload.

    GPS metadata is removed on-device before upload — a privacy detail most apps never mention, let alone handle proactively.

    PWA: An App Without the App Store

    openGym is a Progressive Web App. Installed to a phone's home screen, it behaves like a native app — full-screen, offline-capable, push notifications. No App Store review, no Google Play listing.

    This aligns with the self-hosted philosophy: app-store review is uncontrollable; a PWA bypasses that risk, at the cost of discoverability. An Android APK is also provided, but the core experience is the PWA.

    Structural Balance: Poliquin and Thibaudeau Strength Theory

    openGym implements "structural balance" ratios from strength coaches Charles Poliquin and Christian Thibaudeau. The core idea: strength across muscle groups should follow specific proportions. If your bench press vastly exceeds your rowing, shoulder injury risk rises.

    Example ratios:

  • Poliquin standard: bench:row = 1:1
  • Thibaudeau standard: relative strength ratios across muscle groups
  • ATG (Ass to Grass) squat standard
These ratios are computed automatically from your training data and flagged when out of range. Another instance of coaching logic — not just recording data, but interpreting it into actionable advice.

---

openGym isn't revolutionary. No AI, no blockchain, no Web3. What it does is: rebuild an app category that SaaS hijacked, with genuine engineering integrity.

Data ownership, field-level merging, passkey auth, offline-first, structural balance algorithms — these aren't flashy features; they're fundamentals done right. When 1,494 stars pour in within a day, they're not voting for "a good fitness app" — they're voting for "my data should belong to me."

Tags

#opengym#self-hosted#fitness-tracker#data-sovereignty#pwa#passkey#crdt#open-source

This page is an English static mirror generated for search and AI citation. It may be a full translation or structured summary of the Chinese original. Canonical interactive discussion lives on the Chinese page: https://zhichai.net/topic/178635705