Case Study · Personal Project

Budget G.P.A.

A personal finance app that grades your month like a report card: a letter grade and a 4.0 GPA across five weighted pillars. I took the scorecard method I use professionally on cloud spend and rebuilt it for individuals, then spent most of the effort making sure the grade deserves to be trusted. Built solo, end to end.

5 Weighted Pillars
38 / 84 / 99 Overspender, Typical, Saver
188 Automated Tests
13 Edge Functions

The Verdict

Budgeting apps show you data. Almost none of them render a verdict.

1Number a person can act on: a GPA on the familiar 4.0 scale
$39.99Per year for Pro, against $109 for YNAB and $99.99 for Monarch
5Pillars, so the grade can say which part of your month cost you

At work I grade enterprise cloud subscriptions with a weighted scorecard, and the effect is immediate: a letter grade ends the debate about whether things are fine. Personal finance apps have the opposite problem: endless charts, categories and balances, but no answer to the only question people have, “am I doing okay?”

So the grade is the product. Every month you get a report card: a letter grade, a GPA, and the top fixes that would raise it. The competition competes on feature breadth; this app competes on a single legible number.

One Month’s Report Card

Five pillar scores, each from 0 to 100, weighted into one grade. The numbers below are illustrative, run through the app’s real weights.

PillarWeightWhat It MeasuresExample ScorePoints
Budget Adherence35%How closely actual spending matches each category’s budget8830.8
Financial Safety25%Emergency fund, debt to income, and cash left at month end8020.0
Spending Stability15%Whether spending holds steady month to month, in dollars9013.5
Needs vs Wants15%How close the split is to a 50/30/20 framework or your own targets8512.8
Forecast Accuracy10%How well your budgets predicted what you actually spent787.8
Overall100%Weighted total, then a letter grade and a GPA84.9B

The Grade Scale

GradeScore RangeGPA
A (A+, A, A−)90 to 1003.7 to 4.0
B (B+, B, B−)80 to 892.7 to 3.3
C (C+, C, C−)70 to 791.7 to 2.3
D (D+, D, D−)60 to 690.7 to 1.3
F0 to 590.0

Pillar By Pillar

What each pillar counts, what it deliberately ignores, and why.

Each category is scored on how far actual spending sits from its budget.

  • Over budget is penalized 2 times, under budget 0.6 times at month end, with strict (4 and 1) and relaxed (1.5 and 0.5) presets for Pro users. Larger dollar overages penalize more than small ones.
  • Mid-month, spending is graded on pace. Fixed costs like rent hit on the 1st and are never prorated; variable categories are paced, with penalties damped early in the month so one grocery run does not look like a blowout.
  • Savings are one-sided. Saving more than planned never lowers a grade, and moving money into savings is never counted as spending. The failure mode of a naive distance-from-budget score is punishing people for saving too much.
  • One-time planned expenses can be excused from the discipline pillars, so a planned car repair does not tank a month.

Emergency fund, debt to income and month-end cash, weighted 40, 35 and 25 by default, with Safety Net and Debt Focus presets.

  • Emergency fund follows the FinHealth steps: 1 month of essential expenses scores 50, 3 months 75, 6 months 100, a straight line between, so the first month counts the most. Cash counts unless it is linked to another goal; investments count at 80% if you turn them on.
  • Debt to income follows lender practice: 15% or less scores 100, 36% scores 80, 43% scores 60, 50% scores 30, and 60% or more scores 0, with a small bonus when the ratio improves.
  • Month-end cash: more than 15% of income left scores 100, and ending at zero scores 50.

Households’ spending moves about 30% month to month, so the pillar is built to forgive ordinary variation and catch real spikes.

  • A spike is a rise above 50% and costs 15 points; steady rises cost 1 point per percent, capped at 25. Spending less than last month never counts against you.
  • Changes are measured in dollars, not as a share of income. A flat $110 insurance bill used to look volatile whenever income moved.
  • A floor of $25 or 10% of the budget, whichever is larger, means one charge landing in a different month is not a spike.
  • A rise that holds the next month is a new normal. A new subscription raises the total once and then stays level. A category with no spending is not graded.

The 50/30/20 framework caps needs and wants and sets a floor for savings. Spending less on needs or wants is never a problem, so the pillar only counts going over.

  • Saving more than 20% never lowers the grade. Presets shift the split for other situations: 40/20/40 for aggressive savers and 65/20/15 for high cost of living.
  • Savings under the target still count, so a household that overspends on needs and saves nothing cannot hide behind the other pillars.

The average miss between budget and actual, weighted by each category’s share of the budget, over the last six months.

  • The first 10% of the average miss is free; past that, the balanced preset costs 1.5 times the excess, with stricter and more relaxed presets for Pro users.
  • A 20% miss grades a B, since a 20% miss is a good forecast when natural swings are around 30%.

Grading Against Published Standards

A grade is only fair if meeting the standard earns an A. I tested each pillar against the benchmarks and found five places the math graded healthy behavior as failing.

PartWhat The Standard SaysWhat The App DidWhat It Does Now
Needs vs Wants50/30/20 caps needs and wants; spending less is never a problemUnder target after month close was penalized like over: saving 60% graded D+, while overspending on needs and saving little graded BOnly over-target counts; saving 60% is A+
StabilityTypical household spending moves about 30% a month (JPMorgan Chase Institute)A category rising 30% every other month graded FSpike at 50%, swing penalty halved and capped; a 30% rise earns about a B
Emergency FundFinHealth Score: 6+ months is 100, 3 to 5 is 75, 1 to 2 is 50A straight line to 6 months: 1 month scored 17The FinHealth steps: 50, 75, 100
Debt To IncomeLenders’ standard is 36% or less for all debt (the 28/36 rule)A compliant 36% graded F36% scores 80; 15% or less scores 100
ForecastVariance practice: 5% fine, 10% reviewA 20% miss scored 70 (C−)10% grace, then 1.5 times; a 20% miss scores 85
38F: a household that overspends every month
84B: a typical household
99A+: a saver

Only Honest Inputs Get Graded

A grade computed from inflated numbers is worse than no grade, and real bank data is adversarial.

Sync

Plaid link, sync and webhooks run in server-side functions. No third-party key ever ships in the app.

Classify

Your rules apply automatically. Claude’s suggestions queue for review. Everything else stays uncategorized.

Exclude

Transfers are a third state, outside income, spending and every pillar. Planned one-time spend is excused.

Score

A pure TypeScript module on the device, with one source for every headline figure.

Alert

A server function mirrors the same exclusions, so alerts never contradict the grade.

Money And Trust

Free is genuinely useful. Pro pays for the two things that cost money per user.

$3.99Per month, with the first month free
$39.99Per year
$99.99Lifetime, capped at 500 slots a year

Why Fixes Kept Coming Back

Each device pass found 40 or more issues, and the fixes added new ones. The way out was finding the causes behind the symptoms.

CauseEvidenceWhat Changed
No shared building blocks24 screens shared 6 components; 45 separate stylesheets; dates formatted 13 different ways; 76 native alert menus in 21 filesA small UI kit and one formatting module, plus a pre-build script that fails on raw font sizes, native alert menus, stray switches and sentence-case labels
Two truths per numberIncome read three ways on three screens; 7 of 41 findings in one pass were the same number computed twiceOne source per headline figure, a lint rule, and a test that fails if a screen computes its own
Screens showed the engine, not the answerRaw 0 to 100 scores, “MAPE,” “Shortfall Score”Status words and a letter grade on every row; the math lives on the website
Fixes were big203 commits and about 10,000 lines changed in about two days; shared components moved every screen at onceA design freeze until 2.0, severity levels, and approval for any shared-component change
I marked things fixed that were notA finding reopened after it was called done; some fixes only hold on a deviceFixed means seen on a device in the next build, and the ship bar is two clean passes in a row
Ten styles multiplied everythingEach style in light and dark was 20 sheets per screenThree styles at launch, swept against a route inventory of 31 routes, 3 styles and 2 schemes
A misconfigured excludeTypeScript silently skipped checking the whole app for weeks, masking ten real errorsThe gate runs the type checker, a migration-grants check and the tests before any commit

Under The Hood

One Expo codebase for both stores, a Supabase backend that owns every sensitive operation, and third-party services kept strictly server-side.

App

Expo and React Native with TypeScript and Expo Router. The scoring engine runs on the device and is unit-testable in isolation. Live on iOS and Android.

Supabase

Postgres with row-level security on every table, 36 migrations, and 13 Deno Edge Functions: sync, classification, alerts, webhooks, feedback and deletion.

Services

Plaid for bank sync, the Claude API for classification, RevenueCat for purchases and Sentry for crashes.

React Native Expo TypeScript Zustand Supabase Plaid Claude API RevenueCat Sentry Jest Maestro

A score people trust is worth more than a dashboard people ignore.

The through-line with my professional work is exact. The corporate scorecard works because a VP can glance at a C+ and know where to look. Budget G.P.A. bets the same is true for a person and their own money, and that the hard part is not the grading math but making sure the inputs deserve to be graded.
 Visit budgetgpa.com
 Back to Projects