AI expense tracker, Android and web, 2026
ThoughtExpense
Expense trackers die from the logging tax. ThoughtExpense removes it: type what you spent the way you would say it, and the AI parses, categorises, dates, and learns from every item. An Android app, a web app, and a production API, designed and shipped solo.
- Client
- Own product
- Role
- Product, design, mobile, web, backend, and DevOps
- Stack
- React Native, Next.js, Node.js, PostgreSQL, Redis, Gemini
What it changed
- About 26,000 lines of TypeScript across three codebases, 45+ REST endpoints, 15 mobile screens, 21 web routes.
- The parsing pipeline learns from corrections, so categorisation gets more consistent the longer someone uses it.
- Free and premium tiers with Google Play billing, webhook reconciliation, and a compliant account-deletion flow.
The problem
Every expense tracker asks for the same tax: pick a category, pick a date, type an amount, repeat. Most people quit inside two weeks and the insights die with the data.
The thesis was simple. If capture costs nothing, everything downstream (budgets, insights, advice) becomes possible. So the whole product is built around one interaction: type what you spent in plain words. One input, zero forms.

Latency is designed, not suffered
Both clients run a debounced on-device parser and a small keyword categoriser, so item counts and category chips appear before any network call. Composing works offline; only saving needs the server.
The single model call is shown as staged progress, saves are batched into one request, and every heavy endpoint has an async variant backed by a job queue so phones never hold a long connection open.

Statistics decide, the model narrates
Anything that must be right is kept away from the language model. Anomaly detection, large-transaction flags, trend detection, and waste detection are pure functions over currency-normalised data with conservative, documented thresholds.
The model then writes the narration under strict rules: ground every insight in the actual numbers and never invent a figure that cannot be derived from the data.

Reliable under a flaky dependency
Model calls retry with backoff and then cascade through a three-model fallback chain. A hand-authored 175-item category catalogue overrides the model when it hits, and low-confidence items are returned for review instead of being silently saved.
Rate limits are keyed by user rather than IP, because the target market sits behind carrier-grade NAT where per-IP buckets punish innocent people. Cache failures can never break a request.
