A privacy-first, offline personal finance tracker built with Kotlin Multiplatform & Compose Multiplatform
One codebase β Android, iOS, and Desktop.
| Platform | Status | Notes |
|---|---|---|
| π€ Android | β Complete | In Google Play closed testing β public release coming soon |
| π iOS | π§ In progress | Runs the shared Compose app; native SwiftUI port underway |
| π₯οΈ Desktop (JVM) | π§ In progress | Compose desktop target wired; polishing in progress |
π± Android is feature-complete and going live on the Play Store shortly. iOS and Desktop share the same business logic and are being finished next.
ExpenseTrackr helps you record, categorize, budget, and analyze your personal finances β with your data staying on your device. There are no accounts and no cloud sync of your financial records: every expense, income, budget, and category lives in a local database you fully own.
It's built as a single Kotlin Multiplatform codebase that renders a native UI on Android, iOS, and Desktop via Compose Multiplatform, following a clean, modular MVI architecture.
- True multiplatform β domain, data, and UI shared across 3 platforms from one codebase (~10k lines of Kotlin, 16 Gradle modules).
- Offline-first & private β financial data never leaves the device; only anonymous crash/usage diagnostics are collected (opt-in-friendly, no ads, no data selling).
- Production-grade engineering β clean architecture, MVI, dependency injection, custom Gradle convention plugins, R8 minification, and a real Play Store release pipeline.
- Fully localized β 24 languages with an in-app language switcher (no app restart required).
- Log expenses and income with name, amount (βΉ), category, sub-category, date/time, and notes.
- Income & salary tracking kept separate from spend math, so budgets/analytics stay accurate.
- Add an expense in 3 taps or fewer from anywhere.
- 9 pre-seeded categories + unlimited custom categories (emoji icon + color).
- Sub-categories under any category (e.g. Food β Tea, Breakfast).
- Safe deletes: warns when a category/sub-category still has linked transactions.
- Interactive donut chart β tap a slice to highlight the category and see its amount & share.
- Spent-vs-Saved breakdown and spending-over-time bar chart.
- Stat cards: top category, average daily spend, income, savings rate.
- Overall monthly budget + optional per-category budgets.
- Color-coded progress (green / yellow / red) and pre-overspend warnings.
- "Allow over budget" option for flexibility.
- This Week Β· This Month Β· Last Month Β· This Year Β· Custom range.
- Filter state persists per screen.
- Export everything to CSV β
expenses.csv+incomes.csvβ into an ExpenseTrackr folder in shared storage that survives clearing app data / reinstalling. - Restore/merge from those files, de-duplicated by database ID. Categories are stored as text and recreated on import, so a backup is fully self-sufficient and readable in Excel/Sheets.
- App lock with a 6-digit PIN and optional biometric (fingerprint/face) unlock with PIN fallback.
- PIN stored as a SHA-256 hash; biometrics handled by the OS (no biometric data stored).
- 24 languages (Indian + world), including English, Hindi, Telugu, Tamil, Bengali, Marathi, Gujarati, Kannada, Malayalam, Punjabi, Urdu, Chinese, Spanish, Arabic, and more.
- In-app language switcher that overrides the system locale (RTL supported).
- Material 3 (Material You) design, light/dark/system themes, dynamic color on Android 12+.
- Smooth transitions, bounce-tap feedback, and thoughtful empty states.
- Share App action and a guided onboarding flow.
- Firebase Crashlytics + Analytics (Android) for anonymous crash reports and aggregate usage β used only to improve stability, never your financial data.
| Layer | Technology |
|---|---|
| Language | Kotlin (Multiplatform), Swift (iOS host) |
| UI | Compose Multiplatform, Material 3, Material Icons Extended |
| Architecture | Clean Architecture + MVI (State / Action / Event), unidirectional data flow |
| DI | Koin (core + compose-viewmodel) |
| Navigation | Compose Navigation with type-safe, @Serializable routes |
| Persistence | Room (KMP) + androidx.sqlite bundled driver; DataStore (preferences) |
| Async | Kotlinx Coroutines & Flow |
| Serialization / Time | kotlinx.serialization, kotlinx.datetime |
| Logging | Kermit |
| Diagnostics (Android) | Firebase Crashlytics & Analytics |
| Build | Gradle (Kotlin DSL), version catalog, custom convention plugins (build-logic), R8 minify + resource shrinking |
A clean, modular MVI design with a strict one-way dependency direction:
androidApp / iosApp / desktopApp
β (host + platform bridges)
shared (App.kt β Compose nav host)
β
feature/* (presentation only β one screen module each)
β
core:design-system β core:presentation β core:domain
core:data β core:database, core:domain
core:domainβ pure Kotlin: models, repository interfaces,Result/DataError,DateFilter,AppSettings.core:dataβ Room + DataStore implementations;PinHasher(expect/actual SHA-256), Koin modules.core:presentationβ shared UI utilities, the string-resource catalog,BiometricAuthenticator&ShareHandlerplatform bridges.core:design-systemβ theme + reusable components (cards, charts helpers, PIN pad, motion).sharedβ root ComposeApp()+ navigation; hosts the app on all platforms.feature/*β 8 feature modules, each a self-contained MVI screen set.
Every screen follows the same MVI contract: XxxState Β· XxxAction Β· XxxEvent Β· XxxViewModel (exposes StateFlow + event Channel, single onAction) Β· a stateless XxxScreen Β· a XxxRoot that wires DI + navigation.
Multiplatform abstractions are handled cleanly via expect/actual (DB builder, DataStore, PIN hashing, locale) and Compose CompositionLocal bridges (biometrics, sharing) with per-platform implementations.
| Module | Screens |
|---|---|
dashboard |
Category dashboard, sub-category drilldown, filtered expenses |
expenses |
Expense list + search, add/edit with date-time picker & budget guard |
analytics |
Donut chart, spent-vs-saved, spending-over-time, stat cards |
budget |
Monthly + per-category budgets, allow-over-budget |
categories |
Manage categories & sub-categories |
settings |
Settings, About/Privacy/Terms, notifications, app-lock, language, Backup & Sync, Share |
applock |
PIN / biometric unlock |
onboarding |
Language picker + intro pager |
At a glance: 16 Gradle modules Β· 18 screens Β· 15 ViewModels Β· 24 languages.
- Category β
id, name, icon (emoji), colorHex, isDefault, budgetAmount?, type (EXPENSE/INCOME), createdAt - SubCategory β
id, name, categoryId (FK), createdAt - Expense β
id, name, amount, categoryId (FK), subCategoryId? (FK), notes?, type (EXPENSE/INCOME), expenseDate, createdAt - AppSettings (DataStore) β theme, language, app-lock type & PIN hash, lock timeout, reminders, budgets, onboarding flag
Income and expenses share one table, discriminated by
type, keeping the schema simple while separating the two in all spend/budget/analytics math.
- Your money data stays on your device β expenses, income, and budgets are never uploaded or shared.
- The only data leaving the device is anonymous crash reports and aggregate usage analytics (Firebase), used solely to improve reliability β never the content of your financial records. No ads, no data selling.
- Full policy:
docs/privacy-policy.html.
Requirements: JDK 11+, Android Studio (latest), Xcode (for iOS), and a google-services.json in
androidApp/ (from your own Firebase project) for the Android build.
# Fast common-code check (compiles all shared/feature code)
./gradlew :shared:compileKotlinJvm
# Android debug APK
./gradlew :androidApp:assembleDebug
# Android release bundle (signed β see keystore.properties)
./gradlew :androidApp:bundleRelease
# iOS framework link check
./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
# Desktop app
./gradlew :desktopApp:runiOS: open iosApp/iosApp.xcodeproj in Xcode, pick a simulator, and Run. The shared Shared
framework builds via a Gradle build phase, Koin starts from App.init(), and the shared Compose UI loads.
- β Android feature-complete β Play Store closed testing β public release (soon)
- π§ iOS: native SwiftUI screen-by-screen port (currently hosting the shared Compose app)
- π§ Desktop (JVM) polish
- π Recurring transactions, home-screen widgets, richer charts
Revanth Kumar Jilakara π§ jrevanth101@gmail.com Β· π github.com/revanthkumarJ
Released under the MIT License.
Built with β€οΈ using Kotlin Multiplatform & Compose Multiplatform.
