Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 20ace674a35b849ffda63b30
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
AGENTS.md
# Split Split is a free expense splitter for groups, and a free alternative to Splitwise. It is an OpenApp in the OpenApps free apps store (https://free-apps.openapps.xyz/), owned by the OpenApps team. ## What it promises - Free, with no limit on groups or expenses, no ads and no paid tier. Never add a cap, an upsell or tracking. - No sign-up. Every visitor is a guest account created in the browser. - Anyone with a group's link can see and change the group. The random group id is the link's secret. - AI assistants can do everything a person can through the public API (`functions/api.ts`), documented in `public/llms.txt` and `public/openapi.json`. Keep both true whenever the API changes, and keep `public/index.md` in step with the landing page. ## How it is built - `index.html` is the static landing page that search engines and AI crawlers read. Keep its copy, FAQ and JSON-LD in sync with what the app does. - `src/` is the React app. `/` mounts the start column (the groups this browser opened, then the create form) into the landing; `/g/<groupId>` hides the landing and shows the group. `?add=1&title=&amount=` and `?settle=1` on a group link open a filled-in sheet, for links assistants send. - `src/lib/mine.ts` is what a browser remembers in localStorage: the groups it opened (`split:groups`) and which person it is in each (`split:me:<groupId>`). `split:new:<groupId>` marks a group this browser just created, for the "send the link" notice. The guest session is the client library's own. - The shared look is `public/kit.css` (dialogs, menus, skeletons, empty and error states, the phone action bar). Use its pieces before adding styles to `src/styles.css`. - `functions/lib/split.ts` holds the money math for both the app and the API. Amounts are integers in the currency's minor unit, splits always add up exactly, and balances always sum to zero. - `functions/lib/config.ts` holds the app id and the site URL used in links. - `policy.json` holds the data rules. Reads need a join record (`groups/<id>/joins/<userId>`), and creating that record needs only the group id. That is what makes the link the permission without letting anyone list groups. ## Working on it `npm install && npm run build` typechecks and builds `dist/`. Ship changes through previews and releases as your runtime instructions describe; the app is an OpenApp, so nobody deploys it directly. Check a change by creating a group, adding expenses with each split mode, recording a payment, deleting and undoing, and calling the API with curl. Check phones at 390px wide: the action bar, sheets and the "Which one are you?" step. ## Voice Plain words, short sentences, no jargon, no em dashes. Say what happens, not how clever it is.
Change history
Publish quality pass from owner chat
Bind agent address in policy constants
Quality pass: cleaner group page, phone polish, fuller API, sourced comparison
Bounded source sync
Bounded source sync