Burrow is a personal project I built to explore the offline-first architecture pattern and experiment with server-side AI for practical, everyday problems: receipt parsing, expense categorization, and splitting a bill with friends.
What I built
Offline-first, now cross-platform. All data lives locally using SQLDelight, with a well-defined sync boundary — the app works fully without a network connection. I later migrated the codebase to Kotlin Multiplatform, moving the domain, data, and presentation layers into a shared module so the same offline-first architecture now runs natively on both Android and iOS, with only Keystore/Keychain-backed crypto and a handful of platform-bound screens left per-target.
AI-powered receipt scanning. Photographing a receipt (or a PDF) sends the image to a Supabase edge function that calls the Gemini API to extract line items, quantities, and nominal charges, and to suggest expense categories from the merchant and item descriptions. Running the model server-side keeps the API key out of the client and lets me iterate on prompt quality independently of a client release — parsing accuracy and category quality both improved noticeably after moving prompt engineering to the edge function.
Split bill, voice-assisted. A five-step wizard turns a scanned receipt into a settled group expense: OCR pre-fills items, quantities, and charges; a paint-mode assignment screen lets you tap or drag to assign items to people; and a live voice-dictation mode adds participants as you say their names, confirming each addition with inline feedback instead of a blocking dialog. The flow supports partial splits, per-person breakdowns with receipt thumbnails, and editing a bill after it’s saved.
Security. Biometric authentication gates access to the password vault. No credentials are stored in plaintext, and all sensitive data is encrypted at rest — AES/CBC via Android Keystore on Android, Keychain-backed on iOS.
CI/CD pipeline. Automated testing, versioning, and Play Store deployment via GitHub Actions. Every commit triggers unit tests; every merge to main triggers a staged rollout. The pipeline made solo maintenance sustainable through the KMP migration and beyond.
Why I built it
I wanted a personal finance tool that didn’t require cloud connectivity or account creation. The receipt scanning feature started as an on-device experiment, then moved to a Supabase-hosted Gemini edge function to protect the API key and improve parsing accuracy. Split bill grew out of a genuinely recurring annoyance — manually itemizing a group dinner receipt — and became the feature I iterated on most, from OCR-driven pre-fill through to voice-assisted participant entry. The Kotlin Multiplatform migration was a deliberate stress test of the offline-first architecture: if the layering was clean, porting to iOS should mostly be a matter of swapping platform-bound leaves, not rewriting the core.