Skip to content
All builds

Tip & Bill Splitter PWA

What it does for you

An installable, offline-capable bill splitter, tax, tip, even or by-share splits, any currency, exact-to-the-cent.

Tip & Bill Splitter PWA screenshot

Screenshots

Tip & Bill Splitter PWA screenshot 1

In more detail

An app for splitting a restaurant check: bill, tax, tip, and each person's share, in any currency. You can add it to your phone's home screen and it keeps working with no signal. It also makes sure the shares add up to the exact total, down to the last cent.

Honest limits

There's no automated test file for the money math. The splits were checked in the running app, and the offline test was a one-time scripted run. Everything was verified in headless Chrome; the case study doesn't record testing on a real phone.

How I built it

Claude Code, about 2 hours, starting on June 22 and wrapping on the 23rd. I gave a short brief and made four decisions: push the math as far as it goes, full installable-app depth, a warm receipt and diner palette, and all four of the persistence features on offer. Claude Code wrote the splitting engine, the offline plumbing, and the UI in one pass.

It splits evenly or by shares, handles tax as a percent or a flat amount, lets you tip on the subtotal or after tax, and can round each person up to a nice number with the extra going to the tip. Amounts are typed on a custom keypad where each digit shifts into the cents, like an ATM.

We needed app icons and didn't want image libraries, so Claude wrote gen-icons.mjs, a small PNG encoder in plain Node that draws the icon set. It also wrote serve.mjs, a tiny zero-dependency server, so the app had a real origin to run from. Screenshots landed nowhere at first because headless Chrome saves relative to its own folder, not mine, so we passed absolute Windows paths. For the offline claim, we didn't just assert it. We loaded the app in headless Chrome, killed the dev server, and reloaded. It rendered fully from cache.

What I learned

  • Bill splitting is a rounding problem, not a division problem. Do the math in whole cents and hand out the leftover cents with a largest-remainder method, so every share adds back to the exact total.
  • A service worker only makes an app fully offline if the app makes zero outside requests. Keeping every file, font included, local is what actually made it work.
  • You can make real app icons, including the maskable kind, with no image libraries at all.
  • For typing money on a phone, the ATM-style keypad beats a decimal field, and reading each currency's decimal places from Intl.NumberFormat makes yen come out right with no cents.

What carried forward

serve.mjs shows up here first, and it stuck. #8, #9, and #10 each shipped with one, and in September the shared build brief made "serve.mjs on port 5100 plus the project number" standard for every builder. The absolute Windows path fix for headless screenshots carried forward too. The whole-cents approach to money came back later in #18 and #48.

If I took it further

I'd add receipt scanning so you assign items with a tap instead of setting weights, and a share link or QR code so each person can see what they owe.

#007 Built with Claude Code June 23, 2026

Want one like this?