How ajay-naik/bill-splitter works
1. Overall shape
This is a client-side React single-page app built with Vite. The repository contains no server code, so the whole bill-splitting workflow runs in the browser, with external API calls used only for receipt parsing.
2. Application entry and shell
index.html and src/main.jsx are the bootstrapping layer. src/App.jsx is the top-level application shell that likely wires routing and global layout, while src/styles/Global.css, index.css, and App.css provide app-wide styling.
3. Route-driven user flow
The main UX is split into page-level views under src/pages/:
- Home.jsx — landing / start point
- Scanner.jsx — receipt upload and OCR-based parsing
- Manual.jsx — manual item entry
- Person.jsx — assign items to people
- Summary.jsx — final owed amounts
This suggests a linear workflow where users either scan or enter data, then assign items, then review totals.
4. Core business flow: bill splitting
The central data flow is: receipt or manual items → people selection → per-person totals → summary. The app’s important rule is item-level ownership: each item can be assigned to one or more people, while tip and tax are distributed evenly across all participants.
5. Scanner subsystem
src/Api/BillParser.jsx is the main integration boundary for the AI receipt path. The README indicates it combines Tesseract.js OCR with the Gemini API to extract item names and prices from receipt images. This is the only explicit external service boundary in the repo.
6. Manual entry subsystem
Manual.jsx and the reusable item-entry components support a non-AI path where users add items, quantities, and rates by hand. This is an alternative input source, but it feeds the same downstream splitting logic as the scanner.
7. People assignment and split logic
Person.jsx appears to be the decision point where each bill item is assigned to specific diners. The architecture likely stores item-to-person associations here, then computes owed amounts based on those selections plus shared tip/tax.
8. Shared UI components
src/components/ contains reusable presentation pieces:
- Button.jsx
- BackButton.jsx
- Grid.jsx
- NewItem.jsx
- input.jsx
These form the reusable UI layer across multiple pages, separating interaction widgets from page-specific flow logic.
9. Styling and presentation boundaries
Styling is split between component/page CSS and global styles under src/styles/. The repo also mentions Bootstrap in the README, so the UI is a mix of framework styling and custom CSS rather than a fully custom design system.
10. Runtime/configuration boundary
The app depends on a browser-exposed env var, VITE_GEMINI_API_KEY, which means the Gemini integration is configured at build time through Vite. vite.config.js and eslint.config.js cover build and code-quality tooling, reinforcing that this is a frontend-only repository.
11. Deployment and external footprint
The README says the app is deployed on Vercel, so the production artifact is a static frontend bundle. There is no evidence of persistence, authentication, or backend storage; the “share summary” feature is therefore likely client-side sharing rather than a backend-hosted account system.
12. Useful diagram boundaries
For an architecture diagram, the main boxes should be: React app shell, page-based workflow, shared UI components, receipt parsing pipeline (OCR + Gemini), and computed split summary. The important arrows are from user input to parsing/entry, then to assignment, then to calculation and display.
Main entry points: App.jsx App.jsx · Person.jsx Person · Manual.jsx Manual · Summary.jsx Summary
Components 18
App shell
Bootstraps the SPA and applies global layout and styles.
- index.html · Browser entry point loaded by Vite.
Bill_splitter/index.html - main.jsx · Mounts the React app into the DOM.
Bill_splitter/src/main.jsx - App.jsx · Top-level application shell and route/layout wiring.
Bill_splitter/src/App.jsx
Workflow pages
Route-level views that drive the bill-splitting flow.
- Home · Start screen and entry into the flow.
Bill_splitter/src/pages/Home.jsx - Scanner · Uploads receipts and triggers parsing.
Bill_splitter/src/pages/Scanner.jsx - Manual · Manual item creation and bill input.
Bill_splitter/src/pages/Manual.jsx - Person · Assigns bill items to diners and distributes shared charges.
Bill_splitter/src/pages/Person.jsx - Summary · Shows per-person owed totals and final split.
Bill_splitter/src/pages/Summary.jsx
Shared UI
Reusable interface components used across pages.
- Button · Primary reusable action button.
Bill_splitter/src/components/Button.jsx - BackButton · Navigation/back action component.
Bill_splitter/src/components/BackButton.jsx - Grid · Reusable grid/layout structure for forms and items.
Bill_splitter/src/components/Grid.jsx - NewItem · Adds and edits bill items in the manual workflow.
Bill_splitter/src/components/NewItem.jsx - input · Shared input control used across forms.
Bill_splitter/src/components/input.jsx
Receipt parsing
Client-side OCR and AI extraction boundary for scanned receipts.
- BillParser · Receipt extraction pipeline combining OCR and Gemini API calls.
Bill_splitter/src/Api/BillParser.jsx
Styling
Global and component-specific CSS layers.
- Global.css · Application-wide base styling.
Bill_splitter/src/styles/Global.css - App.css · Styles for the app shell and major layout regions.
Bill_splitter/src/styles/App.css - Button.css · Styles for shared button components.
Bill_splitter/src/styles/Button.css - index.css · Base stylesheet loaded with the app.
Bill_splitter/src/styles/index.css
Connections 23
- index.html → main.jsx: loads · HTML bootstraps the React entry point.
- main.jsx → App.jsx: mounts · Entry point renders the app shell.
- App.jsx → Home: routes to · Initial landing view.
- App.jsx → Scanner: routes to · Receipt scanning flow.
- App.jsx → Manual: routes to · Manual bill entry flow.
- App.jsx → Person: routes to · Item assignment flow.
- App.jsx → Summary: routes to · Final summary view.
- Scanner → BillParser: parses with · Scanner delegates receipt extraction to the parser boundary.
- Manual → NewItem: uses · Manual entry builds bill items through the reusable item form.
- Manual → Grid: lays out · Uses shared layout structure for item editing.
- Person → Grid: lays out · Uses grid-like presentation for people and assignments.
- Person → Summary: feeds · Assignment choices determine the computed totals.
- BillParser → Person: produces items for · Parsed receipt items flow into the splitting step.
- BillParser → Summary: feeds totals · Parsed bill data contributes to final calculation.
- Home → Button: uses · Landing actions use shared buttons.
- Scanner → input: uses · Upload and form fields reuse the shared input control.
- Manual → input: uses · Manual item forms reuse the shared input control.
- Person → BackButton: uses · Navigation between steps uses the back control.
- Summary → Button: uses · Summary actions use shared buttons.
- App.jsx → App.css: styled by · Shell-specific stylesheet.
- App.jsx → Global.css: styled by · Global stylesheet applies across the app.
- main.jsx → index.css: styled by · Base stylesheet is loaded at startup.
- Button → Button.css: styled by · Shared button component styling.