A Kotlin Multiplatform vocabulary learning app targeting Android, iOS, and Web (Kotlin/Wasm).
Built with Compose Multiplatform, Clean Architecture, and Event Sink MVVM.
- Study Dashboard — Track learning progress with vocabulary stats, progress ring, distribution bar, and learning stage breakdown
- Flashcard Review — Spaced-repetition flashcards with tap-to-flip, recall rating, and completion tracking
- Import Words — Type words manually with translations/descriptions, or import from
.txtfiles - AI-Powered Import — AI-generated vocabulary by target language, proficiency level, and topic
- Word Manager — Browse, search, edit words, and track mastery levels
- Offline TTS — Text-to-speech pronunciation for 13 languages (Sherpa ONNX / Piper models)
- Profile & Leaderboard — Learning streaks, weekly activity, and leaderboard
- Subscriptions — RevenueCat-powered premium features
- Onboarding — Language selection, proficiency level, and AI-generated starter vocabulary
composeApp App entry point, DI graph (Koin), platform hooks
presentation Compose screens, ViewModels, navigation, UI state
domain Use cases + domain models (pure Kotlin)
data Repository implementations, SQLDelight DB, Ktor data sources
core HTTP client, Try<T>, BaseViewModel, UiState, OnEvents
platforms Platform-specific bridges (Firebase, notifications, secure storage)
design-system Reusable Compose components and theming
resources Compose Multiplatform strings and assets
utils Shared helper functions
test Shared test utilities
build-logic Custom Gradle convention plugin
iosApp Swift iOS entry point
Data flow: View → ViewModel → UseCase → Repository → DataSource
# Android debug APK
./gradlew composeApp:assembleDebug
# iOS framework (simulator)
./gradlew composeApp:linkDebugFrameworkIosSimulatorArm64
# Web (Kotlin/Wasm dev server)
./gradlew composeApp:wasmJsBrowserDevelopmentRun
# Compile common (shared) Kotlin code
./gradlew composeApp:compileKotlinMetadata# Run all common unit tests
./gradlew composeApp:cleanAllTests composeApp:allTests
# Android unit tests only
./gradlew composeApp:testDebugUnitTest
# Web browser tests
./gradlew composeApp:wasmJsBrowserTest- Copy
local.defaults.propertiestolocal.properties - Fill in backend URL, Google OAuth client IDs, RevenueCat keys, and signing config
- For iOS builds, run
./scripts/sync-ios-config.sh
| Area | Technology |
|---|---|
| Language | Kotlin 2.3.0 |
| UI | Compose Multiplatform 1.10.2 |
| Targets | Android (minSdk 24), iOS, Web (wasmJs) |
| DI | Koin 4.1.1 |
| Database | SQLDelight 2.3.1 (multiplatform) |
| Networking | Ktor 3.4.0 (auth interceptor + auto token refresh on 401/403) |
| Auth | KMPAuth + Firebase Auth (Google OAuth, Apple Sign-In) |
| Subscriptions | RevenueCat KMP |
| Navigation | androidx.navigation-compose with bottom tabs |
| Image Loading | Coil 3.4.0 |
| TTS | Sherpa ONNX (Piper models, 13 languages, offline) |
| Analytics | Firebase Analytics + Crashlytics |
| Testing | Turbine, kotlin-test, coroutines-test |
| Static Analysis | Detekt 1.23.8 |
| CI/CD | GitHub Actions (build.yml, test.yml) |
Splash → [authenticated?] → Main App (tabs)
→ [not authenticated] → Auth Gate (Google/Apple sign-in)
→ Onboarding (language, level)
→ Vocabulary Preview (import suggestions)
→ Main App
Detailed docs live in doc/:
file-map.md— Find any file by featureapi-endpoints.md— All backend API endpointsspaced-repetition.md— 7-bucket SRS algorithmdi-setup.md— Koin module organizationauth-flow.md— Login, token refresh, logout flowsarchitecture-vision.html— Current vs target architecture with migration roadmap
./scripts/bump-version.sh --hotfix # patch bump
./scripts/bump-version.sh --minor # minor bump
./scripts/bump-version.sh --major # major bump
# Trigger CI build/deploy via GitHub CLI
gh workflow run ci.yml -f platform=ios -f version_bump=none