Inspiration
It all started when my brother "Coach Erabi" a well known online fitness personal trainer in our country was using a very old method to manage his customers and members by just contacting them via social media platform or offline inside the GYM he had to contact , track , and support them via social media chats ...etc It worked, but it wasn’t scalable: updating programs took hours, progress got lost in chat threads, reminders were inconsistent, and clients struggled to find everything in one place , not only these he forgot who subscribed when ...? also he faced a lot of problems to accept payment from them Me as a mobile developer thought of an idea why don't we just make it more smart and easy for him that will also be easy and smart for his customers and to allow us to gain and scale for more and more customers easy The problem I saw Spend more time on admin than on coaching. Clients need structure: clear workouts, how-to videos, meal guidance, and gentle nudges to stay consistent. Progress gets scattered across tools; habits break when the internet does. What I wanted to build One hub for workouts + how-to videos + personalized diet—with easy meal swaps. Real-time chat to keep coach and client aligned. Smart reminders (next workout, water, motivation) that actually help adherence. Progress tracking that’s visual and meaningful. Offline-first so a bad connection never breaks a good habit. Easy way to manage subscriptions and payment.
What it does
ErabiFit is a cross-platform fitness app built with Kotlin/Compose Multiplatform for Android and iOS. It helps users stay consistent with their training and diet through: Personalized workout plans with video guidance. Custom diet programs tailored to individual goals, with the ability to swap and edit meals. progress tracking for workouts, achievements, and body metrics. Direct chat with Coach Erabi for real-time support. Motivational reminders including water intake alerts, workout notifications, and daily quotes. unlike any other apps it's not a generic mobile app for fitness and nutrition but it's for the coach you trust and want him side by side with you like if he were with you at the gym in simple terms a Personal Trainer App
How we built it
Two years ago we launched our first version using Flutter. It helped us validate the idea quickly and reach early users. But as we scaled and needed more advanced integrations (native notifications, reminders, in-app billing, offline-first Room DB, etc.), which all of that was only possible in flutter using some community SDK or Package which was okay but not as much powerful as we wanted sometimes we face a lot of problems with some package which was outdated or deprecated or the developer stopped using or maintaining it , as an android developer sometimes I built my own bridges but I had no strong knowledge with the iOS ecosystem to build their bridges as well not only that but I had to write many layers of code layer in swift iOS , layer in android kotlin and the layer I will be using in flutter dart , it was not making a lot of sense to me so months ago I decided to go native which means using KMP especially I developed multiple scalable apps using KMP even before IOS Compose Reaches It's stable it was at that time also excellent , not only this we already using KMP at our Company Which serves a huge number of users and has a very complex business and technical logic "Point of sale systems " , also flutter does not provide a convincing way in architecture or modulating the project as Gradle or Kotlin Provides espcilay that we have 2 apps module that share almost every business logic between so I decided to rebuild everything with Kotlin Multiplatform to get full native power while still sharing business logic across iOS and Android with access to all IOS SDK with The Language I adore and know well kotlin it seems like the iOS is technically an android app built with Kotlin so I started with the project as multi module with multiple modules for business logic , technical and platform specific apis , like alarms or notifications and 2 :app modules TraienrApp and CustomerApp
Architecture ( the whole app follows a clean & simple architecture )
all the logic that is needs a platform specific implementation is interfaced and abstracted inside the common source set then got implemented inside each platform source sets :alarm : the module that manages the alarms -> AlarmManager (Android ) UNUserNotificationCenter (IOS)
:analytics : the module that manages the analytics and crashlytics , using Firebase for both + CocoaPods on IOS
:crypto : the module that encrypts user local data and preferences - KeyStore(Android ) CoreCrypto(IOS)
:database: the module manages local database (Room KMP ) IOS & Android
:erabiTime: the module that manages date and time manipulations and formatting (KotlinXDateTime)
:modelHub : business logic module for data classes related to business
:network the module manages remote calls and firebase implementations (Ktor+Firebase Android , CocoaPodsFirebase IOS )
:notification - module for managing local notifications - NotificationManager (Android ) UNUserNotificationCenter(IOS ) + Remote FCM Notifications from Firebase For iOS & Android
:parser - module for managing serializations and dserializations of data (KotlinXSerializations JSON )
:permission - module managing the permissions for both Android - IOS
checking permissions requesting permissions even multiple permissions was managed on IOS
:preferences - module managing the local presences for user (DataStore KMP Android & IOS )
:purchase the module that abstracts usage of RevenueCat KMP SDK
:reminder :- the module that manages the reminders for the user Calendar ContentProvider (Android) EKEventStore (IOS)
:shared - the module that is considered for sharing ui or decency injection between modules , or app modules (**Koin + Compose Multiplatform)
:auth : module for managing auth for user , we use Google And Apple Sign in , CredentialsManager **(Android ) **ASAuthorizationController(IOS )
:calculations - a domain business specific module for all diet , nutrition , macros & training math.
:uiHub : the whole components , system design and compose ui layers needed across the whole project
:utility shared: Cross-cut helpers, extensions which has also a lot of platform specific implementations
buildConfig , uuidGenerations , UrLauncher (Intent or NSURL) , errorHandling , imagePicking , imageCompressions , fileManager , coroutinesExtensions , resourcesLoading (Res from compose resources ) networkConnectivity ConnectivityManager (Android) nw_path_monitor (IOS)
*Technologis Used *
Kotlin Multiplatform + Compose Multiplatform — Single codebase for UI and logic
Navigation Compose (common) — type-safe navigations in common cmp
ViewModel (common) — lifecycle-aware state holders using coroutines/flows in common
Coil (Compose) — fast image loading/caching in common cmp
Kotlinx DateTime — DateTime Management in common
DataStore (KMP) — reactive preferences in common
Room (KMP) — typed SQL database on common
Kotlinx Serialization
Ktor — Coroutine-first HTTP client
Coroutines & Flows — structured concurrency and reactive streams in common
Koin — Lightweight DI
Paging (KMP) — common paging library
RevenueCat KMP — Unified purchases, in common
Firebase (Analytics/Crashlytics/Messaging) — Usage insights, stability tracking, and push.
Sign in with Apple / Google — Native auth providers wrapped behind a common interface.
CryptoKit/Keystore + Keychain — Secure secrets and encrypted stores with platform HSMs.
Local & Push Notifications — Scheduled reminders and real-time alerts via a shared API.
Background tasks — Alarms, refresh, and work scheduling mapped to each platform’s APIs.
File & Media bridges — Native pickers, compression, and safe-sharing utilities.
Testing (kotlin.test ) — Unit tests
Challenges we ran into
APNs to Firebase Integration (iOS Push Notifications) Passing apple push notification service (APNs) tokens seamlessly into firebase on iOS needed the iOS application delegate which needed to write small swift code to make it work Implemented a Kotlin/Native CInterop bridge to expose Swift-side logic to Kotlin. This allowed iOS native code to call back into Kotlin, ensuring APNs tokens were correctly registered with Firebase. after the delegate fires the token
Multi IosApp inside 1 KMP Project was solved by generating a new iosApp and copying it inside the project
Paging Support with Room Created a custom invalidation interface and implemented a mechanism that ties PagingSource to SQL query changes manually, ensuring that data updates were reflected properly
Accomplishments that we're proud of
successfully built Erabifit – Personal Trainer as a fully-fledged Kotlin Multiplatform app that runs natively on IOS & Android without relying on ThirdParites or packages or bridges to make use of native mobile OS cabibilities and now we have access to all the native , cabibilities , SDK for the operating systems , I feel now I own my own app
What we learned
we know know the value and the powerfulness of Kotlin Multi Platform to build a scalable production grade native mobile apps gained a much deep knowledge of IOS Ecosystem as well as Android , how to architect a large scaled apps , and share code between 2 apps modules in 1 project in scalable way
What's next for Erabifit - Personal Trainer
we are thinking to provide a way for the all personal trainers to have their own smart solutions using our app and customers chooses who to subscribe to in one app
Log in or sign up for Devpost to join the conversation.