# ajay-naik/bill-splitter architecture

> Architecture diagram of the GitHub repository ajay-naik/bill-splitter, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ajay-naik/bill-splitter
- Repository: https://github.com/ajay-naik/bill-splitter

## Overview

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: [`Bill_splitter/src/App.jsx`](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/App.jsx) (App.jsx), [`Bill_splitter/src/pages/Person.jsx`](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Person.jsx) (Person), [`Bill_splitter/src/pages/Manual.jsx`](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Manual.jsx) (Manual), [`Bill_splitter/src/pages/Summary.jsx`](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Summary.jsx) (Summary)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_entry["App shell"]
  node_node_index_html["index.html<br/>SPA entry<br/>[index.html]"]
  node_node_main["main.jsx<br/>bootstrap<br/>[main.jsx]"]
  node_node_app["App.jsx<br/>shell<br/>[App.jsx]"]
end

subgraph group_group_flow["Workflow pages"]
  node_node_home["Home<br/>landing page<br/>[Home.jsx]"]
  node_node_scanner["Scanner<br/>scan page<br/>[Scanner.jsx]"]
  node_node_manual["Manual<br/>entry page<br/>[Manual.jsx]"]
  node_node_person["Person<br/>assignment page<br/>[Person.jsx]"]
  node_node_summary["Summary<br/>results page<br/>[Summary.jsx]"]
end

subgraph group_group_ui["Shared UI"]
  node_node_button["Button<br/>ui control<br/>[Button.jsx]"]
  node_node_back["BackButton<br/>ui control<br/>[BackButton.jsx]"]
  node_node_grid["Grid<br/>layout component<br/>[Grid.jsx]"]
  node_node_newitem["NewItem<br/>item form<br/>[NewItem.jsx]"]
  node_node_input["input<br/>field component<br/>[input.jsx]"]
end

subgraph group_group_parse["Receipt parsing"]
  node_node_billparser["BillParser<br/>ocr+gemini<br/>[BillParser.jsx]"]
end

subgraph group_group_style["Styling"]
  node_node_global_css["Global.css<br/>global styles<br/>[Global.css]"]
  node_node_app_css["App.css<br/>shell styles<br/>[App.css]"]
  node_node_button_css["Button.css<br/>component styles<br/>[Button.css]"]
  node_node_index_css["index.css<br/>base styles<br/>[index.css]"]
end

node_node_index_html -->|"loads"| node_node_main
node_node_main -->|"mounts"| node_node_app
node_node_app -->|"routes to"| node_node_home
node_node_app -->|"routes to"| node_node_scanner
node_node_app -->|"routes to"| node_node_manual
node_node_app -->|"routes to"| node_node_person
node_node_app -->|"routes to"| node_node_summary
node_node_scanner -->|"parses with"| node_node_billparser
node_node_manual -->|"uses"| node_node_newitem
node_node_manual -->|"lays out"| node_node_grid
node_node_person -->|"lays out"| node_node_grid
node_node_person -->|"feeds"| node_node_summary
node_node_billparser -->|"produces items for"| node_node_person
node_node_billparser -->|"feeds totals"| node_node_summary
node_node_home -->|"uses"| node_node_button
node_node_scanner -->|"uses"| node_node_input
node_node_manual -->|"uses"| node_node_input
node_node_person -->|"uses"| node_node_back
node_node_summary -->|"uses"| node_node_button
node_node_app -->|"styled by"| node_node_app_css
node_node_app -->|"styled by"| node_node_global_css
node_node_main -->|"styled by"| node_node_index_css
node_node_button -->|"styled by"| node_node_button_css

click node_node_index_html "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/index.html"
click node_node_main "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/main.jsx"
click node_node_app "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/App.jsx"
click node_node_home "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Home.jsx"
click node_node_scanner "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Scanner.jsx"
click node_node_manual "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Manual.jsx"
click node_node_person "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Person.jsx"
click node_node_summary "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Summary.jsx"
click node_node_button "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/Button.jsx"
click node_node_back "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/BackButton.jsx"
click node_node_grid "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/Grid.jsx"
click node_node_newitem "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/NewItem.jsx"
click node_node_input "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/input.jsx"
click node_node_billparser "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/Api/BillParser.jsx"
click node_node_global_css "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/Global.css"
click node_node_app_css "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/App.css"
click node_node_button_css "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/Button.css"
click node_node_index_css "https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/index.css"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_index_html,node_node_main,node_node_app toneBlue
class node_node_home,node_node_scanner,node_node_manual,node_node_person,node_node_summary toneAmber
class node_node_button,node_node_back,node_node_grid,node_node_newitem,node_node_input toneMint
class node_node_billparser toneRose
class node_node_global_css,node_node_app_css,node_node_button_css,node_node_index_css toneIndigo
```

## Components

### App shell

Bootstraps the SPA and applies global layout and styles.

- [index.html](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/index.html): SPA entry · Browser entry point loaded by Vite. · `Bill_splitter/index.html`
- [main.jsx](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/main.jsx): bootstrap · Mounts the React app into the DOM. · `Bill_splitter/src/main.jsx`
- [App.jsx](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/App.jsx): shell · 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](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Home.jsx): landing page · Start screen and entry into the flow. · `Bill_splitter/src/pages/Home.jsx`
- [Scanner](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Scanner.jsx): scan page · Uploads receipts and triggers parsing. · `Bill_splitter/src/pages/Scanner.jsx`
- [Manual](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Manual.jsx): entry page · Manual item creation and bill input. · `Bill_splitter/src/pages/Manual.jsx`
- [Person](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Person.jsx): assignment page · Assigns bill items to diners and distributes shared charges. · `Bill_splitter/src/pages/Person.jsx`
- [Summary](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/pages/Summary.jsx): results page · Shows per-person owed totals and final split. · `Bill_splitter/src/pages/Summary.jsx`

### Shared UI

Reusable interface components used across pages.

- [Button](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/Button.jsx): ui control · Primary reusable action button. · `Bill_splitter/src/components/Button.jsx`
- [BackButton](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/BackButton.jsx): ui control · Navigation/back action component. · `Bill_splitter/src/components/BackButton.jsx`
- [Grid](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/Grid.jsx): layout component · Reusable grid/layout structure for forms and items. · `Bill_splitter/src/components/Grid.jsx`
- [NewItem](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/NewItem.jsx): item form · Adds and edits bill items in the manual workflow. · `Bill_splitter/src/components/NewItem.jsx`
- [input](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/components/input.jsx): field component · 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](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/Api/BillParser.jsx): ocr+gemini · Receipt extraction pipeline combining OCR and Gemini API calls. · `Bill_splitter/src/Api/BillParser.jsx`

### Styling

Global and component-specific CSS layers.

- [Global.css](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/Global.css): global styles · Application-wide base styling. · `Bill_splitter/src/styles/Global.css`
- [App.css](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/App.css): shell styles · Styles for the app shell and major layout regions. · `Bill_splitter/src/styles/App.css`
- [Button.css](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/Button.css): component styles · Styles for shared button components. · `Bill_splitter/src/styles/Button.css`
- [index.css](https://github.com/ajay-naik/bill-splitter/blob/main/Bill_splitter/src/styles/index.css): base styles · Base stylesheet loaded with the app. · `Bill_splitter/src/styles/index.css`

## Connections

- 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.
