An athlete's numbers, read against the athlete's own history.
HoopLab is an iPhone app a professional basketball player is building for personal use. It takes overnight data from a Fitbit wrist tracker and short daily inputs, compares each value with the athlete's own baseline, and links every threshold to a published study.
The demo runs right here with a synthetic athlete. Nothing leaves your browser. The app's interface is in Turkish.
Why build it
Wearables tune their verdicts to an average user. A professional athlete's values don't fit that frame: a very low resting heart rate, heavy weekly loads and long recovery needs all get misread.
Some things a watch can't measure at all: how hard a session felt, which muscle is sore, when the next game is. HoopLab asks for those in a 30-second morning check-in and a few taps after training, then judges each night against the athlete's previous four weeks.
How a number reaches the screen
Data
The Google Health API syncs every hour: overnight HRV, sleeping heart rate, sleep, SpO2, skin temperature and workouts. The athlete adds check-ins, session effort, a pain map, meals, water, games and trips.
Engine
A deterministic, tested TypeScript package computes baselines, training load, region load and nutrition targets. Same input, same output.
Evidence
Each threshold the engine uses is a rule in the repo, and each rule points to sources verified by DOI or PMID.
Explanation
A language model writes the morning summary from numbers the engine already computed. A server-side checker drops any sentence whose citation or number doesn't hold up.
iPhone
Expo and React Native. Estimates carry a "Tahmin" (estimate) label, and red flags point to a doctor instead of a comment.
Every threshold has a source
The day's state is built on a personal band: the last 7 days compared with the 28 days before, give or take half a standard deviation. That band is not hard-coded in the app. It lives in a rule file, and the rule names its sources. Here is the actual rule from the repo, read when this page was built:
{
"id": "toparlanma-bant",
"rolling_days": 7,
"baseline_days": 28,
"sd_multiplier": 0.5,
"metrics": ["hrv", "sleep_hr"],
"sources": [
"manresa-rocamora-2021",
"vesterinen-2016",
"buchheit-2014",
"duking-2021"
]
}
The 4 sources it points to
- manresa-rocamora-2021Heart Rate Variability-Guided Training for Enhancing Cardiac-Vagal Modulation, Aerobic Fitness, and Endurance Performance: A Methodological Systematic Review with Meta-Analysis
- vesterinen-2016Individual Endurance Training Prescription with Heart Rate Variability
- buchheit-2014Monitoring training status with HR measures: do all roads lead to Rome?
- duking-2021Monitoring and adapting endurance training on the basis of heart rate variability monitored by wearable technologies: A systematic review with meta-analysis
Across the app: 50 rules in 12 modules, backed by 118 sources. A source without a verifiable DOI or PMID doesn't go in, and every push re-checks them against retraction notices. Where a study comes from endurance athletes or football rather than basketball, the rule says so.
Screens




Demo mode, synthetic athlete. The pictures follow your light or dark setting.
Privacy
The repository is public, and none of the athlete's data is in it. Health data lives only in the owner's Supabase project, with every table locked to one owner. API keys stay on the server. A guard scans every commit, every commit message and the full git history for secrets and personal details. Screenshots, tests and this demo use synthetic data only.
How it's built
The athlete builds HoopLab with Claude Code, and the whole record is in the repo: 53 decision records with the options weighed, 35 session reports, a lessons file, and a single state document every session starts from. Type checks, unit tests, end-to-end tests and the source check run on every push.
Expo SDK 57 and React Native in strict TypeScript, Expo Router, Supabase (Postgres with row-level security, Edge Functions, pg_cron), Google Health API, Claude API on the server only, three.js for the 3D figure.