I built CIBI because budgeting apps show up too late

I made CIBI because I kept noticing a dumb gap in budgeting apps.
They are pretty good at telling you what happened after the month is over. They are much less useful when you are standing somewhere, looking at a price, and trying to decide whether buying the thing is going to make next week annoying.
That was the whole starting point. Not a grand fintech vision. Not a bank. Not a “personal finance operating system.” Just a small mobile app for one awkward question: can I buy this right now?
The app should do the math, explain the tradeoff, and then get out of the way.
The public landing page is at getcibi.com.
The bit that bothered me
A price tag does not feel connected to a savings goal. A $79 purchase feels like the object in your hand. It does not naturally feel like less room in your wants budget, or a few extra days before a goal is funded.
So I wanted the app to translate the price into something more concrete. Not “you are bad with money.” Not “you deserve this.” Just: here is what this does to the month. Still your call.
That tone became more important than I expected. Finance apps drift into being weirdly parental very quickly. Green means good. Red means shame. Copy starts sounding like a gym poster. I did not want that.

The current decision screen in the iOS simulator. The manual path matters as much as scanning, because nobody wants to fight OCR in a checkout line.
What I actually built
The v1 loop is intentionally narrow: enter or scan a price, classify the purchase as a Need or Want, check the monthly budget, and return Safe, Careful, or Over.
“Safe” means it fits. “Careful” means it fits but tightens the buffer. “Over” means the purchase crosses the guardrail or pushes the goal in the wrong direction. None of those are commands. They are states. The user still decides.
I also kept one active savings goal. That was partly a product call and partly self-defense. Multiple goals sound useful until the first version becomes a dashboard project with a mobile app attached. One goal keeps the decision readable.
The stack
CIBI is an Expo React Native app, iOS-first, Android-ready enough that I am not making future me hate present me.
The stack is TypeScript, Expo Router, Zustand, React Query, TanStack Form, Zod, MMKV, Supabase, RevenueCat, Jest, and React Testing Library. OCR uses Expo Camera plus ML Kit text recognition. Product classification starts with local rules because the first version does not need to be clever everywhere.
1const price = await scanOrEnterPrice()
2const bucket = classifyAsNeedOrWant(price.context)
3const verdict = checkBudget({ price, bucket, month, goal })
4
5show(verdict) // Safe | Careful | OverThe actual app is messier than the pseudo-code, obviously. There is auth, onboarding, local finance records, sync queues, premium setup, reminders, settings, and all the small mobile edge cases that appear when you touch a keyboard, a camera, or the App Store.
Why local-first
I did not want the first useful moment to require bank sync. That adds trust friction, geography problems, and a bunch of infrastructure before the user has even seen a verdict.
So the app can work from salary, budget setup, manual entries, OCR, and local records. Supabase is there for auth and sync. MMKV keeps the local model usable. RevenueCat handles subscriptions because implementing purchase logic by hand is not a personality trait I am trying to develop.
What was harder than expected
The hard part was not the verdict calculation. The hard part was keeping the app from becoming every other finance app.
Every obvious feature tries to expand the surface area: recurring reports, charts, forecasts, multiple goals, bank sync, imported statements, spending insights, AI advice. Some of those might be useful later. But if they slow down the moment-before-purchase loop, they are not v1.
That constraint helped. It made the product less impressive on paper and more usable in the actual moment it is supposed to serve.
Current state
The app has the core mobile shell, onboarding, budget setup, decision engine, scan/manual entry flow, goals, local storage, auth/sync plumbing, premium wiring, settings, and tests around the risky pieces. It is still a side project. It still has rough edges. That is fine.
The useful thing, at least for me, was turning a vague finance anxiety into a specific interaction: price in, tradeoff out.
That is CIBI. Small question. Small app. A lot of annoying details hiding underneath.
Share this article
Send it to someone who would use the context.
Add your perspective
The thread is stored in GitHub Issues through Utterances, so the conversation stays portable and tied to the article URL.
Loading comments connects to GitHub and may use third-party storage in your browser.