P-07 · BUILD / PROJECT · 2026 SHIPPED

SplitLah

Bill-splitting for trips, shared rent, and mahjong nights. Multi-currency, and the maths is tested.

STACK: Next.js 16SupabaseTanStack QueryPWA

What it is

A bill splitter that handles the three situations my friends actually get into: a trip where six people pay for things in four currencies, a flat where rent and utilities recur, and a mahjong night where money moves every hand.

The existing apps do the first case adequately and the third not at all. Mahjong isn’t a shared expense: it’s a sequence of small settlements with winners, losers, partner arrangements and someone who paid for the food. Modelling that as “split a bill five ways” produces a number nobody accepts.

How it works

There are three split workflows rather than one generic one. Travel splits handle uneven participation across days. General splits cover recurring shared costs. Mahjong splits are scored pot by pot: winners, losers, partners, and meal money kept separate from play.

Multi-currency covers SGD, CNY, USD, MYR and HKD, with the FX rate fixed per split, so the numbers stop moving after the trip ends. That’s the only behaviour anyone will tolerate.

A travel split, with who paid for what and the running balance

Settlement has two views, because people want two different things. “Fewest transfers” optimises the graph down to the minimum number of payments. “By activity” keeps person-to-person debts intact so you can see who owes what for which dinner. The first is efficient. The second is the one that ends arguments.

Settlement drawn as a map: four transfers close the whole trip

The parts that had to be right

Money maths and settlement optimisation are unit-tested, because a cent of drift across forty transactions destroys trust in a tool like this permanently. The mahjong scoring engine was ported from an earlier app of mine and kept intact rather than reimplemented.

Access control is enforced at the database layer, with no privileged path around it. Splits are shared by invite link and update live for everyone in them. Receipt photos attach to entries, and charts show where the money went.

Where it stands

Shipped, running as an installable PWA, and iterated on for about six months, mostly in response to arguments it failed to settle.