Every serious lifter knows progressive overload is the only way to grow. But tracking it manually — remembering last week's weights, deciding when to go heavier — is friction that kills consistency.
Most apps make you do the maths. FitLogic does it for you.
After each set you tap one button: 😊 easy · 💪 normal · 😤 hard. That's it. The app recalculates your weights overnight and your next session is already loaded when you open it.
┌─────────────────────────────────────────────────────────┐
│ You train → Rate each set → App recalculates weights │
│ │
│ 😊 Easy ──→ +2.5 kg next session │
│ 💪 Normal ──→ same weight │
│ 😤 Hard ──→ -2.5 kg next session │
└─────────────────────────────────────────────────────────┘
No spreadsheets. No manual logging. No guessing. The app tracks 39 exercises across every session and applies the progression algorithm independently to each one.
- Personalised plan generation — Full Body, Upper/Lower, or Push/Pull/Legs split selected automatically by goal, fitness level, and available days
- 8 program variants — randomised on each generation so no two users get identical plans
- Automatic progressive overload — weights adjust after every session based on difficulty rating
- "Last time" coaching — every set shows your previous weight and reps so you always have a reference
- Personal Record detection — backend compares every set against all previous workouts; triggers celebration screen and push notification
- 12-week GitHub-style heatmap — see your training consistency at a glance
- Weekly volume tracking — real calendar weeks (Mon–Sun) reset each Monday, with week-over-week percentage change
- 21 Achievements across Workouts, Streak, Volume lifted, and Personal Records
- Rest timer — auto-starts after logging a set with animated countdown
- Streak system — consecutive workout day tracking with best-streak record
- Workout Complete screen — animated result screen with PR callout, duration, and next session preview
- One daily workout slot — completed workouts are locked for the day, new slot opens at 05:00
- JWT authentication — 7-day mobile tokens
- Password reset via email — 6-digit code, 5-minute expiry, sent via Gmail SMTP
- Expo Push Notifications — PR alerts, welcome message (requires dev build)
┌─────────────────────────────────────────────────────────┐
│ React Native (Expo) │
│ LoginScreen HomeScreen PlanScreen ProgressScreen │
│ WorkoutCompleteScreen SettingsScreen ... │
└──────────────────────┬──────────────────────────────────┘
│ HTTPS / JSON
┌──────────────────────▼──────────────────────────────────┐
│ FastAPI Backend │
│ /auth /user /plan /workout /progress │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
│ │ Services │ │ Core │ │ Workers │ │
│ │ auth │ │ jwt │ │ progression engine │ │
│ │ plan │ │ bcrypt │ │ PR detection │ │
│ │ workout │ │ email │ │ plan generator │ │
│ │ progress │ │ push │ │ │ │
│ └──────────┘ └──────────┘ └──────────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────────────▼──────────────────────────────────┐
│ PostgreSQL (Supabase) │
│ users · exercises · workout_plans · plan_days │
│ plan_day_exercises · workout_logs · set_logs │
│ password_reset_tokens │
└─────────────────────────────────────────────────────────┘
| Layer | Technology |
|---|---|
| Mobile | React Native · Expo SDK 53 · React Navigation |
| Backend | Python 3.13 · FastAPI · SQLAlchemy 2 (async) |
| Database | PostgreSQL · Alembic migrations · Supabase |
| Auth | JWT · bcrypt |
| Gmail SMTP · aiosmtplib | |
| Push | Expo Push API · httpx |
| Testing | Custom async test suite · 37 tests · 100% pass |
| Tool | Version |
|---|---|
| Python | 3.11+ |
| Node.js | 18+ |
| PostgreSQL | Any (or Supabase free) |
| Expo Go | Latest |
cd FitLogic
pip install -r requirements.txt
# Copy and fill in your credentials
cp .env.example .env
# Create tables
python -m alembic upgrade head
# Seed exercise library (39 exercises)
python seed.py
# Start API server
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reloadInteractive API docs: http://localhost:8000/docs
cd FitLogicApp
npm install
# Set your backend URL in services/api.ts
# BASE_URL = 'http://<your-local-ip>:8000/api/v1'
npx expo start --lanScan the QR code with Expo Go (iOS or Android) on the same Wi-Fi network.
# .env
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/fitlogic?ssl=require
SECRET_KEY=your-256-bit-secret
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080 # 7 days
MAIL_USERNAME=your@gmail.com
MAIL_PASSWORD=xxxx-xxxx-xxxx-xxxx # Gmail App Password
MAIL_FROM=your@gmail.com
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
DEBUG_MODE=falseGmail App Password: Security → 2-Step Verification → App Passwords
View all 13 endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/auth/register |
— | Register, receive JWT + welcome email |
POST |
/auth/login |
— | Authenticate, receive JWT |
POST |
/auth/forgot-password |
— | Send 6-digit reset code to email |
POST |
/auth/reset-password |
— | Validate code, set new password |
GET |
/user/me |
✓ | Full user profile |
PUT |
/user/profile |
✓ | Update body stats |
PATCH |
/user/settings |
✓ | Update goal, level, stats |
POST |
/user/push-token |
✓ | Register device push token |
POST |
/plan/generate |
✓ | Generate personalised plan |
GET |
/plan |
✓ | Get active training plan |
GET |
/workout/today |
✓ | Today's full workout with suggested weights |
POST |
/workout/complete |
✓ | Submit results, trigger PR detection |
GET |
/progress |
✓ | Sessions, volume, heatmap data |
cd FitLogic && python test_all.pyAuth ✓ 5/5 register · login · wrong password · duplicate · invalid token
User ✓ 4/4 profile · invalid age → 422 · settings update
Plan ✓ 8/8 generate · 3-day full-body · 4-day upper-lower · regenerate
Workout ✓ 10/10 today · complete · progression · double-submit → 409
Progress ✓ 5/5 sessions · heatmap · volume · exercise tracking
Password ✓ 5/5 forgot · wrong code → 400 · reset · old password invalidated
────────────────────────────────
Passed 37 / 37 • Bugs 0
View full structure
FitLogic/ ← Backend
├── app/
│ ├── core/
│ │ ├── progression.py ← easy / normal / hard weight algorithm
│ │ ├── security.py ← JWT + bcrypt
│ │ ├── email.py ← welcome email + reset code
│ │ └── push.py ← Expo push notifications
│ ├── models/ ← SQLAlchemy ORM
│ ├── schemas/ ← Pydantic validation
│ ├── services/ ← Business logic (no DB queries in routers)
│ └── routers/ ← HTTP layer only
├── alembic/versions/ ← 4 migrations
├── seed.py ← 39 exercises
└── test_all.py ← 37 integration tests
FitLogicApp/ ← Frontend (React Native)
├── screens/ ← 11 screens
├── services/api.ts ← Typed Axios client
├── src/
│ ├── theme/tokens.ts ← Design tokens
│ ├── components/ui/ ← Button · Card · Pill · Segmented · Typography
│ └── utils/registerPush.ts ← Push permission + token registration
└── App.tsx ← Navigation root + SafeAreaProvider
- Daily workout reminders (user-defined time)
- Streak recovery ("Shield" mechanic)
- Workout history feed — last 10 sessions
- 1RM estimator per exercise
- Plate calculator
- Exercise swap within a plan
- Deploy backend to Railway / Render
- Production APK / IPA via EAS Build
- Apple Health + Google Fit sync
| FitLogic | Strong | Hevy | Alpha Progression | |
|---|---|---|---|---|
| Auto progression | ✅ | ❌ | ❌ | ✅ |
| Plan generator | ✅ | ❌ | ❌ | ✅ |
| Free tier | ✅ | ❌ | ✅ | ❌ |
| Open source | ✅ | ❌ | ❌ | ❌ |
| Self-hostable | ✅ | ❌ | ❌ | ❌ |
FitLogic is the only open-source, self-hostable workout tracker with automatic progressive overload built in.
MIT © 2025
Built with FastAPI · PostgreSQL · React Native







