Chia: I Built My Household a Splitwise That Lives in Telegram
A Vietnamese bill-splitting app on Cloudflare Workers — live-editing Telegram notifications, Monday-morning debt reports via cron, and an inbox for machine-suggested expenses.
The Problem With Splitwise
Splitwise is great until you actually live with people. Then the friction shows: everyone needs the app, everyone needs to open the app, and the person who paid for dinner needs to remember to log it before the group chat has moved on to arguing about something else.
Our household already had a perfectly good coordination platform: the Telegram group. So I built Chia (Vietnamese for split) — a bill-splitting app where the web UI is for entering data, but Telegram is where the app actually lives.
The Stack: Aggressively Boring
- Cloudflare Workers for compute, D1 for the ledger, Cron Triggers for scheduling.
- No servers, no containers, no cold-start anxiety, and — at household scale — no bill. There's something poetic about a bill-splitting app that costs 0₫ to run.
The domain model is three transaction types, unified in one table:
- Expenses — who paid, and whether it splits equally or across a chosen subset of members.
- Income — money received on behalf of the group, reducing the collective debt.
- Transfers — settlement payments between members.
Balances are simplified automatically, Splitwise-style: the app collapses the web of who-owes-who into the minimum set of debts.
The Feature That Makes It Work: a Live Telegram Feed
Every transaction pushes a formatted notification into the group's Telegram chat. That part is table stakes. The part that took actual thought:
Editing or deleting a transaction edits or deletes the original Telegram message.
The Worker stores each Telegram message_id alongside its transaction, so the chat history never lies. No "⚠️ correction to my earlier message" noise — the feed always reflects the current ledger. The group chat is the audit log, and it self-heals.
Small recent UX touches in the same spirit: transactions that don't split (personal items logged for tracking) get an explicit "Ko chia" badge — Vietnamese for "not split" — and each payer gets a consistent color across the app, so a glance at the feed tells you who's been fronting the money this week.
Monday Morning Accountability
A Cloudflare Cron Trigger fires every Monday at 9:00 AM and posts the simplified balances into the chat:
Quang: +150,000₫
Ngoan: −150,000₫
This one message quietly killed the awkward "so… about that money" conversation forever. Nobody has to ask; the robot asks. It turns out the optimal amount of social friction for settling debts is zero humans.
The Inbox for Robots
The newest piece is a suggestions endpoint — POST /api/suggestions — an ingest queue where other software can propose transactions. My companion app Tiền (which watches for spending) queues up what it sees; in Chia, each suggestion is one click to accept into the ledger or dismiss.
That converts the app from "a form I must remember to fill in" to "an inbox I triage" — and at least in my household, triaging is a much more reliable human behavior than remembering.
What I'd Tell Past Me
- Meet users where they already are. Nobody in my household opens a bill-splitting app recreationally. Everybody opens Telegram involuntarily.
- Mutable notifications beat immutable ones. Syncing message edits/deletes with ledger state was maybe 30 lines of code and it's the single most trust-building feature in the app.
- Cron is a feature, not plumbing. The weekly summary is the entire retention strategy. Zero notifications between Mondays is a feature too.
- Workers + D1 is a genuinely delightful home for tiny household apps: one
wrangler deploy, no infrastructure to babysit — which, given how much infrastructure I already babysit, matters.