Flutter + SQLite: Building a Financial Tracker From Scratch

Share

A financial tracker sounds like a simple CRUD app until you get to the projections screen. Add, edit, delete an investment — trivial. Show someone what that investment will be worth in five years, compounding monthly versus quarterly versus annually — suddenly you're not writing a form anymore, you're writing a small financial model inside a mobile app. Here's how that build went, using Flutter, Riverpod, and sqflite.

Why Cupertino, and why that choice matters early

The app needed to feel native on iOS specifically, which meant building with Flutter's Cupertino widget set rather than Material. This decision has to happen before you write the data layer, not after — Cupertino's navigation patterns, list styling, and form conventions shape how screens compose together. Retrofitting Material screens into Cupertino later means rebuilding, not restyling.

The core entities were straightforward on paper: Investment, Category, and Nominee. Each needed full CRUD screens — create, list, edit, delete — with sqflite as local storage and Riverpod managing state across them. The genuinely tedious part isn't any single screen; it's keeping three sets of CRUD screens consistent with each other as the app grows, which is where a repeatable pattern for each entity pays off more than clever code in any one of them.

The part that isn't CRUD: monthly projections

The projections screen takes an investment's principal, rate, and a chosen compounding frequency, and shows what it becomes over a chosen time horizon. Compounding frequency is the detail that turns this from a formula into a small design problem: monthly, quarterly, and annual compounding aren't just different multipliers, they change how granular the projection table needs to be, and how you present a number that updates as the user changes assumptions.

The implementation itself uses the standard compound interest formula, but applied per-frequency rather than hardcoded to one. Practically: the number of compounding periods and the periodic rate both depend on which frequency the user picks, and both feed into building the year-by-year (or month-by-month) projection table shown on screen. Getting this right matters more than it seems, because it's the one screen in a financial tracker where a subtly wrong number actually misleads someone about their money.

Why Riverpod for this specifically

State management choices matter more in a CRUD-heavy app than people expect, because the same investment data needs to be visible and stay in sync across the list screen, the edit screen, and the projections screen simultaneously. Riverpod's provider model made it straightforward to have all three screens read from the same underlying data source without manually wiring callbacks between them — change an investment on the edit screen, and the projections screen reflects it without extra plumbing.

What building this actually taught

The unglamorous truth about a financial tracker: the CRUD screens are 70% of the code and 20% of the thinking. The projections logic is the reverse — a small amount of code that requires getting the financial math exactly right, because it's the one part of the app making an implicit promise about the future. That asymmetry is worth remembering before starting a similar build — budget the review time for the calculation logic accordingly, even though it looks like the smallest part of the app on the file tree.

Read more