Local-first intermittent fasting, calorie, weight & workout tracker
Solo Forge is a free and open source, local-first Android fitness app for fasting, nutrition, weight tracking, and workout timing. It is GPL-3.0 licensed and built to keep user data on the device, with no backend, account system, analytics, or cloud telemetry.
The only intentional outbound network request is a user-initiated OpenRouter call for food analysis (photo or text description), using an API key supplied by the user. AI features can be switched off entirely in Settings.
Website: soloforge.dimitroff.work — landing page and privacy policy. Maintained in the separate soloforge-site repo (Cloudflare Pages, deploys on push); update it when a release changes features, screenshots, or the store description.
- Intermittent fasting timer with 16:8, 18:6, 20:4, and 36 hour modes.
- Smart fasting reminders driven by timer state instead of fixed daily spam.
- AI-assisted food analysis (photo or text description) through an automatic OpenRouter model escalation chain, with an off switch in Settings.
- Manual meal entry and one-tap meal presets when the user does not want to use AI.
- Editable food entries, including proportional macro recalculation by total grams.
- Local nutrition tracking with calorie and macro goals.
- Versioned JSON backup: export, import (merge or replace), and an optional auto-backup folder that rewrites the backup file on every data change.
- Weight tracking with edit/delete support, history, charting, and a weekly weigh-in reminder.
- Workout timers:
- simple session timer with pause/resume
- interval timer with periodic audio cues
- exercise/rest toggle timer
- Home dashboard with daily fasting, nutrition, workout, weight, and calendar progress.
- Configurable bottom tabs.
- Local Room migrations with exported schemas and migration tests.
Solo Forge is designed around local ownership of fitness data.
- No backend.
- No authentication.
- No analytics SDKs.
- No crash reporting SDKs.
- No Firebase.
- No broad media, contacts, or logs permissions.
- Android system cloud backup is disabled (
allowBackup=false); device migration uses the explicit export/import flow. - The OpenRouter API key is stored in encrypted local preferences and is never included in backups.
- Backup is explicit: a versioned JSON file exported on demand, or auto-written to a user-selected folder (which the user can sync to Drive/Dropbox themselves).
The app declares INTERNET only for food analysis through OpenRouter. That call happens only when the user starts an analysis; with AI features off, the app makes zero network calls.
Food analysis starts with google/gemini-3.1-flash-lite, escalates to openai/gpt-5.4-mini when confidence is low or hidden/mixed ingredients are likely, and uses google/gemini-3.1-pro-preview only if uncertainty remains.
- Kotlin
- Jetpack Compose
- Material 3
- Single-activity architecture
- Hilt dependency injection
- Room SQLite storage
- DataStore preferences
- EncryptedSharedPreferences for the OpenRouter API key
- WorkManager for scheduled reminders
- Foreground services for active timers
- CameraX for food capture
- Ktor and kotlinx.serialization for OpenRouter
- Coil for image loading
- Hand-rolled Compose charts (no chart library)
- Android Studio with Android SDK installed
- JDK 17
- Android emulator or physical Android device
- Min SDK 26
- Compile SDK 35
- Target SDK 35
Clone the repo and open it in Android Studio, or build from the command line:
.\gradlew.bat assembleDebugThe debug APK is generated at:
app/build/outputs/apk/debug/app-debug.apk
Install on a connected emulator or device:
adb install -r app/build/outputs/apk/debug/app-debug.apkRun the unit tests (backup format, calendar math, food escalation, OpenRouter parsing):
.\gradlew.bat testDebugUnitTestRun the connected Room migration tests with an emulator or device attached:
.\gradlew.bat :app:connectedDebugAndroidTestRun lint:
.\gradlew.bat lintDebugSolo Forge is published on F-Droid as com.kbul.spicycrab. Listing content comes from:
.fdroid.yml
fastlane/metadata/android/en-US/
The fdroiddata recipe uses UpdateCheckMode: Tags with AutoUpdateMode: Version, so pushing a vX.Y.Z release tag is what triggers an F-Droid release (published in roughly 2–7 days). The official recipe deliberately has no AntiFeatures: — the F-Droid reviewer removed the NonFreeNet flag during inclusion review (fdroiddata MR !38080) because the OpenRouter feature is off by default, opt-in, and requires the user's own key. Do not re-add it.
app/src/main/java/com/kbul/spicycrab/
├── MainActivity.kt
├── SpicyCrabApp.kt
├── data/
│ ├── backup/
│ ├── db/
│ └── prefs/
├── di/
├── domain/
│ ├── fasting/
│ ├── nutrition/
│ ├── weight/
│ └── workout/
├── network/
├── notifications/
└── ui/
├── common/
├── fasting/
├── food/
├── home/
├── nav/
├── onboarding/
├── settings/
├── theme/
├── weight/
└── workout/
The package name still uses the original com.kbul.spicycrab namespace. The app-facing brand is Solo Forge.
Room migrations are mandatory. Do not use destructive migration fallbacks.
For schema changes:
- Edit the entity.
- Bump the Room database version.
- Add a migration in
Migrations.kt. - Append it to
ALL_MIGRATIONS. - Build once to export the new schema under
app/schemas/. - Add or update an androidTest migration test.
Brand notes and early SVG assets live in:
BRAND-BRIEF.md
brand/
Solo Forge is licensed under the GNU General Public License v3.0. See LICENSE for the full license text.
Solo Forge is released and published on F-Droid, with debug-signed APKs on GitHub releases. Core features — fasting, food tracking, weight, workouts, dashboard, and JSON backup export/import — are in place; development continues on UI polish and broader device testing.





