Every month I told myself the same thing: "I'm pretty good with money."
Then I'd check my bank balance and feel a little confused. Not broke — just... confused. Where did the $340 go? Ah right, that week of delivery apps. And the other $200? Oh, those "quick" Amazon orders.
The problem wasn't spending. It was visibility. I had no idea where my money actually went until it was gone.
The Experiment
I built a tool called Monee — the idea is dead simple. You paste your bank transactions (CSV, copy-paste, whatever), and it categorizes everything instantly. No account. No bank login. No 14-day free trial.
But here's what I didn't expect: the experiment wasn't the tool. The experiment was what happened when I actually used it.
I exported February's transactions from my bank — a CSV with 47 rows. Pasted it in. Hit "Parse."
In 30 seconds, I saw:
- $1,850 on rent (expected)
- $162 on groceries (seemed fine)
- $47 on dining out (wait, really? that's it?)
- $116 on transport (ubers add up fast)
- $43 on subscriptions (I have a Spotify problem)
But the number that got me? $289 in the "Shopping" category from four Amazon orders I genuinely didn't remember making.
The Two-Pass Parser That Makes This Work
Bank CSV formats are the worst. Every bank has its own idea of what "columns" mean. Some split debit and credit into separate columns. Some use "Posted Date" instead of "Date". Some put amounts in a single column with negative = debit.
I wrote a two-pass column detector:
// Pass 1: Match headers against known aliases
const aliases = {
date: ['date', 'posted', 'transaction date'],
description: ['description', 'merchant', 'payee', 'narrative'],
amount: ['amount', 'debit', 'credit', 'value']
};
// Pass 2: If headers fail, infer from data shape
// A column full of numbers like -47.99, -13.85, +2000.00? That's your amount.
This handles about 90% of bank exports without any configuration. Chase, BoA, Wells Fargo, Capital One, random credit unions — they all work because the pattern matching is flexible enough.
The Categorizer
Once transactions are parsed, each one gets categorized by keyword matching:
const CATEGORY_RULES = {
'Groceries': ['whole foods', 'trader joe', 'safeway', 'kroger', 'wegmans'],
'Transport': ['uber', 'lyft', 'shell', 'exxon', 'chevron', 'parking', 'metro'],
'Subscriptions': ['netflix', 'spotify', 'hulu', 'disotify', 'apple', 'youtube'],
'Dining Out': ['chipotle', 'sweetgreen', 'mcdonald', 'starbucks', 'doordash'],
// ... about 80 merchants total
};
It's not AI. It doesn't need to be. A hash map of 80 keywords gets you to 85% accuracy. The remaining 15%? You click the category badge and change it. Takes 2 seconds.
What Actually Surprised Me
The empty state matters more than the populated state. When you open the app with no data, it looks like nothing. So I added a "Try Sample Data" button that loads a realistic February — rent at 93%, transport at 90%, a few categories in the green. The moment you click it, the app feels alive. That one button is the difference between "neat project" and "oh, I want to use this."
Dark mode isn't a theme choice — it's a data visualization strategy. Purple for actions. Green for "under budget." Amber for "getting close." Red only when you've blown past a limit. The dark background makes the color bars pop like a dashboard, not a spreadsheet.
localStorage is an underrated architecture. No backend. No auth. No GDPR compliance. No server costs. The data lives in your browser and your browser alone. The tradeoff? You can't access it from another device. But for a 10-minutes-once-a-month tool, that's the right call.
What I Learned About My Spending
Back to the experiment. After seeing that $289 in forgotten Amazon purchases, I set up category limits:
- Dining out: $150/month
- Shopping: $200/month
- Transport: $100/month
The next month, I actually stayed under. Not because the tool scolded me — because the progress bars made it visible. Seeing "76% of your dining budget gone" on March 14 hits different than vaguely remembering you ate out a lot.
The Build
This was a one-night build. Next.js 15, Tailwind v4, TypeScript, shadcn/ui. The whole thing is open source.
The hardest part wasn't the code. It was the copywriting. How do you explain "paste your bank CSV and see where your money went" without it sounding like every other budgeting app? I went with: "Know where your money went. Right now." — because that's what it actually does. No fluff.
Try It
Monee — free, no sign-up, runs in your browser.
Export your last month. Paste it. See what's actually happening with your money.
Then tell me I'm wrong about the Amazon thing.
Top comments (0)