An itemized bill-splitting tool. Add participants, enter line items, assign them to specific people, apply tax and tip, and see exactly what each person owes.
- Add/remove participants inline on the same screen as items
- Itemized line items with per-person assignment (checkboxes)
- Tax, tip, and additional fees/discounts split proportionally
- Tip and fee rows can be calculated on pre-tax or post-tax subtotal
- Multi-payer support: one person paid, or split payment across multiple people
- Settlement: minimal set of transactions to settle all debts
- Session auto-saves to localStorage (survives page refresh)
- Fully responsive — works on Safari on iOS, Chrome for Android, and desktop
nvm use # picks up the version from .nvmrc (or: fnm use)
npm install
npm run devThe URL will be shown in the terminal output.
Other scripts:
npm run build # production build → dist/
npm run preview # preview the production build locally
npm run typecheck # run TypeScript without emitting filesDev (hot reload, source mounted as a volume):
docker compose up
# → check `docker compose ps` for the assigned host portProd (static build served by nginx):
docker build --target prod -t bill-split .
docker run -p 8080:8080 bill-split
# → http://localhost:8080Merging to main triggers two workflows:
- Deploy — builds and publishes the site automatically.
- Auto-release — reads the
version:major/minor/patchlabel from the merged PR and creates a new semver tag and release.
PRs require exactly one version label (version:major, version:minor, or version:patch) before merging.
- Branch from
main - Apply a version label to your PR before merging
- The deploy and release workflows run automatically on merge
See AGENTS.md for notes relevant to AI assistants working on this codebase.