An alarm clock app for Android and iOS that looks and behaves like Apple's Clock app — same layout, same wheel picker, same swipe-to-delete list, same rounded settings rows. Built with Kotlin Multiplatform and Compose Multiplatform, so the UI and app logic are written once and shared between both platforms.
- Alarm list with swipe-to-delete and an on/off switch per alarm
- Add/edit screen with the iOS-style scrolling hour/minute/AM-PM picker
- Repeat on specific days of the week, custom labels, and snooze with a configurable duration
- One-time alarms disable themselves automatically after they've gone off, same as stock Clock
- Alarms persist locally with Room, so they survive app restarts
- On iOS, alarms actually ring through AlarmKit (repeat and snooze included), not just a local notification hack
- A lock-screen widget on iOS showing time remaining until the next alarm, updated live by the system with no polling
shared/— nearly everything: UI (Compose Multiplatform), the alarm list/edit screens, the Room database, and platform-specific bits (expect/actual) for things like scheduling and time calculations that can't be shared.commonMain— the actual app, common to both platformsandroidMain/iosMain— platform-specific implementations
androidApp/— thin Android application shell that hosts the shared UIiosApp/— Xcode project. Holds the SwiftUI entry point, the AlarmKit integration, and theShalarmWidgetlock-screen widget extension
Dependency injection is Koin (via its compiler plugin, not KSP), and the database is Room's
KMP flavor (androidx.room3).
Android:
./gradlew :androidApp:assembleDebug
iOS: this one's built via GitHub Actions (.github/workflows/ios-build.yml),
producing an unsigned, ad-hoc-signed IPA as a build artifact — no Mac required to develop
against it, only to sideload and test the result on a real device. If you do have a Mac,
opening iosApp/iosApp.xcodeproj in Xcode works the normal way too.
Local notifications don't reliably ring like a real alarm — no full-screen takeover, no
guaranteed sound at volume, no proper snooze. AlarmKit (iOS 26+) is Apple's actual API for
this, which is also why MinimumOSVersion is set as high as it is.