In development · Internal testing
MinSpend
A native Android expense tracker that turns bank SMS alerts into categorized transactions, budgets and spending reports.
FocusNative Android development
StatusInternal testing

Overview
MinSpend is built with Kotlin and Jetpack Compose, using Room for local data, Hilt for dependency injection and WorkManager for background tasks. Its SMS pipeline scopes parsing rules by bank sender, extracts transaction details and checks for duplicates before saving. The app also includes category budgets, bill reminders, reports, backup tools and a home-screen widget.
The problem
Manual transaction entry is easy to abandon, but automatic import introduces its own problems: inconsistent SMS formats, repeated alerts and separate payments with identical amounts.
Implementation
- Built a native Compose interface for expenses, category budgets, spending history and reports.
- Implemented bank-scoped SMS rules with ordered matching and a fallback for shared message patterns.
- Added reference-aware deduplication across existing records and transactions arriving in the same batch.
- Kept unmatched merchants in an explicit uncategorized state, so users can distinguish unresolved imports from intentionally categorized spending.
- Added background import and reminder workers, CSV/PDF report generation, backup code and an expense widget.
Outcome & status
A working codebase in internal testing. The repository contains unit tests for parsing, reference-aware deduplication, budget math and other business logic; no public adoption or accuracy figure is claimed.
From input to outcome
How it works
Receive
SMS receivers and workers bring transaction alerts into the import flow.
Interpret
Sender-specific rules extract payment details and categorize known merchants.
Reconcile
Reference-aware checks remove repeated alerts while preserving distinct payments.
Use
Room-backed records feed Compose screens, budgets, reports and reminders.
Inside the implementation
Engineering decisions
Same amount does not mean same payment
Two ₹1 payments seconds apart must remain distinct when their bank references differ. Matching references identify duplicates; amount and time are only a fallback when references are missing.
Check duplicates within a batch, too
Checking only the saved database misses repeated alerts in the same scan. The import helper also compares each candidate with records already accepted in that batch.
Give specific bank rules priority
The parser tries issuer-specific rules before shared patterns. Matching is ordered and bounded so a broad rule does not override a more specific interpretation.
Interested in how I build?
Let’s talk