Inspiration
Most finance apps force you to pick a side: you either track your own spending in a budgeting app, or you track what you're owed by friends in a splitting app.
When you pay for a group dinner, you have to log the expense in one app, open another app to split who owes what, and then manually adjust your numbers so your monthly budget still makes sense.
Kaas was built to fix this: tracking what you spend, earn, and owe belongs in the same simple ledger. ────── ## What it does
Kaas is an offline-first personal finance and expense tracker for the money you spend, earn, and owe.
• Track Your Money: Log income and expenses, sort them into custom categories, set monthly budgets or savings goals, and see where your money goes with visual spending charts. • Splits and Loans: Split bills with contacts, keep tabs on informal loans, and see who owes who at a glance. • Flexible Settle-Up: Support for partial repayments—settle up all at once or bit by bit, with full history and undo support. • Optional Anonymous Sharing: Share a split or loan with a contact code so it lands in both ledgers. No email, password, or personal details required. • Privacy & Offline by Default: All your data lives on your device in SQLite. Sharing splits is the only feature that connects to the internet—everything else works 100% offline. • Full Data Portability: Export your data to CSV or create full JSON backups and restore them anytime.
### The Math Behind Kaas
Kaas keeps your real net financial position clear and accurate:
• Cash in hand:
Cash Total = ∑ Income - ∑ Expenses
• Money owed with each contact:
Balance = ∑(Owed to You) - ∑(You Owe)
• Your true net position:
Net Worth = Cash Total + ∑ Contact Balances
All amounts are stored as integers in the smallest sub-unit (cents or paise, A ∈ ℤ) to completely eliminate floating-point rounding errors. ────── ## How we built it
• Flutter: Clean, responsive UI that feels native and fast. • SQLite (sqflite): Local on-device database as the single source of truth. Every transaction, category, contact, and loan is stored locally. • Supabase: Powers optional, lightweight cloud syncing for shared splits using 6-character contact codes without requiring accounts or passwords. • Custom Charts: Built lightweight bar charts and donut charts from scratch using Flutter's CustomPainter—no bloated graphing libraries. • Currency & Font Details: Set up tabular numbers so amounts never shift as digits change, and packaged a tiny ~2KB fallback font so unusual currency symbols (₸, ₴, ₵, ₲, ₮, ₦, ₱) render cleanly without broken "tofu" boxes. • RevenueCat: Integrated an optional "Pro" tip jar via Google Play Billing for users who want to support development—no features are locked behind it. ────── ## Challenges we ran into
• Connecting splits to expenses: When an expense is split, it spawns linked loan records. Handling edits—like changing a bill amount or removing a split person—required writing atomic database transactions so linked loans and contact balances never get desynced. • Partial repayments: People rarely pay back a loan all at once. Modeling partial settlements (R < A) and letting users undo individual repayments without corrupting the running total took careful database design. • Keeping sync truly optional: Designing the app so it never complains, slows down, or breaks when offline, while still letting two people seamlessly sync a bill using just a short code. ────── ## Accomplishments that we're proud of
• One app instead of two: Tracking personal expenses and friend debts in the same workflow feels natural and saves time. • Zero sign-up friction: You can install the app and use every core feature immediately without handing over an email or creating an account. • Fast, clean UI: Handcrafted charts that render smoothly at 60fps and tabular typography that looks clean and stable. • Complete data ownership: Users can back up their entire database to JSON or export to CSV at any time. ────── ## What we learned
• Keep event history separate from balances: Storing repayments as individual transaction events rather than just decrementing a number made tracking history, undoing mistakes, and syncing much simpler. • Integer arithmetic is essential: Storing all currency amounts as integers prevents small rounding errors from compounding over time. • Offline-first builds better apps: Treating local storage as the primary source of truth makes the app faster, more reliable, and naturally private. ────── ## What's next for Kaas
• Group splits: Support splitting a single bill across 3 or more people at once. • Smart recurring expenses: Automatic reminders and tracking for recurring bills and subscriptions. • Multi-currency support: Simple exchange rates for tracking expenses and splits while traveling.
Built With
- flutter
- revenue-cat
- supabase
Log in or sign up for Devpost to join the conversation.