← BACK TO HOME
CASE STUDYDEPLOYED

Khata

ProductROLE — PRODUCT BUILD

A personal finance app for how money actually moves in India — it reads UPI transaction SMS and logs the spend itself, keeps a lending ledger per person, and settles a group trip without anyone having to remember who paid for what.

TYPESCRIPTREACT 19CONVEXCAPACITOR
khata.raja-dev.me
Khata — live preview

PROOF

MEASURED, SOURCED
71
COMMITS IN THE FIRST 48 HOURS
GitHub API — repos/Anuraj-dev/Khata/commits, 3-4 Jun 2026
176
COMMITS ON MAIN
GitHub API — repos/Anuraj-dev/Khata/commits
74 / 76
PULL REQUESTS MERGED / OPENED
GitHub search API — repo:Anuraj-dev/Khata is:pr
OPEN REPOSITORY EVIDENCE (3)
17 DAYS
FIRST COMMIT TO LATEST
GitHub API — 3 to 20 Jun 2026
94.4%
TYPESCRIPT BY BYTES
GitHub API — /languages, 558 kB of 591 kB
265
FILES TRACKED ON MAIN
GitHub API — git/trees/main?recursive=1

THE PROBLEM

WHAT NEEDED SOLVING

This one was built for a specific trip, three days before leaving. Money on a trip with friends moves through UPI in dozens of small payments, and it goes wrong in three predictable ways: the spending itself is never written down anywhere, so the month is a mystery afterwards; money lent to one person disappears from memory, because a loan is remembered for about a week and then it is simply gone; and when one person fronts a bill for the group, the reckoning at the end is done from everyone's partial recollection, which is how friendships get quietly taxed. Every existing tracker asks the user to type each expense in by hand, which is the step nobody sustains past the first week. The objective was an app where the logging happens whether or not anyone remembers to log.

THE APPROACH

HOW IT WAS BUILT

The transaction data already exists on the phone — every UPI payment produces a bank SMS. On Android, a thin Capacitor shell around the web app reads those messages and writes the spend automatically, so the ledger fills itself. Everything else is one Vite and React PWA backed by Convex for queries, mutations and scheduled crons, with Google sign-in through better-auth. Two decisions shaped the data model rather than the UI. Amounts are stored as integers in paise, never as floating-point rupees, because money that is added and split and settled repeatedly will drift if it is stored as a float. And a debt is attached to a person rather than to whatever string the SMS happened to contain — the single decision the whole udhaar feature rests on.

FIELD NOTES

PROBLEMS HIT — AND RESOLVED
  1. 01

    A PERSON, NOT A NAME STRING

    The same friend shows up as a phone number, a UPI VPA, and three different spellings of their name depending on which app sent the message. Keying a ledger on that text produces one balance per spelling, which is exactly the lost-track problem the feature was meant to solve. A contact is instead a person who owns many handles, and their balance rolls up across all of them; duplicates that slip through can be merged after the fact rather than requiring the data to be clean on arrival.

  2. 02

    MONEY IN PAISE, NEVER FLOATS

    Split a restaurant bill three ways in floating-point rupees and the thirds do not add back to the total. Across a trip's worth of splits and settlements the residue accumulates into a figure nobody can reconcile, which destroys trust in a ledger whose only job is being trustworthy. Every amount is stored as an integer count of paise and formatted for display at the very last moment.

  3. 03

    SMS THAT ARRIVES GARBLED

    Bank messages describe the other party inconsistently — truncated merchant names, transliterated shop names, raw payment-gateway strings. Rather than trying to parse the display name, the importer captures the UPI handle underneath it, which is stable. A handle gets named once, by hand, and every future transaction from it is labelled correctly without being touched again.

  4. 04

    THE REACT NATIVE APP THAT GOT ABANDONED

    The first plan was a separate Expo app for mobile alongside the web app — two codebases, two sets of screens, the same logic written twice. It was abandoned mid-build once it was clear the PWA already worked on a phone and the only thing genuinely needing native access was SMS reading. A Capacitor wrapper around the existing web app buys that one capability without a second codebase. The dead Expo directory is still in the repository, marked as abandoned rather than quietly deleted.

CAPABILITIES

WHAT IT ACTUALLY DOES
  • UPI spends logged automatically from bank SMS on Android — no manual entry
  • Udhaar ledger keyed to a person, rolling up every handle and spelling they use
  • Duplicate contacts can be merged after the fact instead of demanding clean data
  • Trip splitter with a one-tap settle-up that closes out remaining transfers
  • Recurring-bill detection from spend history, with a reminder before the due date
  • Per-category budgets with safe-to-spend at a glance