We built a Splitwise alternative where the link is the account
Description and use
PeanutSplit lets friends split expenses without account creation, using a single URL as a bearer credential, deterministic money handling, offline queuing, and secure real‑time updates.
Problem
Friends will not create accounts, so the room URL must serve as invite, login, and data key.
Outcome
PeanutSplit allows friends to split expenses without account creation, using a single URL as a bearer credential, with deterministic money handling, offline queuing, and secure real‑time updates.
Workflow
- Generate a 16‑byte random key, base64url‑encode it, and append it to a readable stem to form the room URL.
- Use the URL as a bearer credential; no recovery or owner override.
- Store money amounts as strings and BigInt; display numbers only.
- Lock FX rates at entry; never re‑price history.
- Queue new expenses offline and replay when online; edits require connection.
- Use SSE to notify clients of changes; clients refetch data; stream carries no room data.
- Route FX and receipt requests through an allow‑listed proxy; containers cannot reach the internet directly.
- Write usage limits into STEWARDSHIP.md to avoid feature gates and paid tiers.
- Deploy as AGPL to keep hosted forks open.
Evidence
If your friends have to make an account, they won’t. So the room URL had to be the whole product: the invite, the login and the data key in one string.
The link is a bearer credential. 16 random bytes, base64url, appended to a readable stem. No recovery, no owner override. Treat it like a key.
Money as strings + BigInt. A Number never touches an amount except for display. Equal splits hand out remainders deterministically.
FX locked at entry. Editing an expense never re‑prices history. Rates are fetched through a same‑origin route so the browser never talks to a second host.
Realtime that leaks nothing. SSE sends "something changed", the client refetches. The stream itself carries no room data.
No egress in prod. Containers can't reach the internet; push, FX and the receipt model go through an allowlisted proxy.
- Record date: 2026-10-09T00:56:01.632Z