Smart, effortless group expense sharing and debt simplification.
Splitzz is a modern, full-stack expense sharing application built for roommates, trips, dinners, and group projects. Say goodbye to messy spreadsheets, complicated debt webs, and awkward money talks.
Features • Tech Stack • Database Architecture • Getting Started • API Documentation • Testing
Splitzz accommodates any sharing scenario:
- Equal Split: Divide expenses evenly across selected group members with remainder cent distribution.
- Exact / Unequal Split: Manually allocate exact rupee or cent amounts per member with real-time validation.
- Percentage Split: Split costs by percentage (e.g. 60% / 40%) with live total validation.
- Shares / Ratio Split: Allocate by relative weights or shares (e.g. 2 parts for a couple, 1 part for a single guest).
Without simplification, a group of 5 friends can generate up to 10 overlapping debt relationships. Splitzz implements a greedy net-balance graph simplification algorithm that reduces total transactions to the mathematical minimum (
- Upload receipt photos directly in the Add Expense modal.
- Automatically extracts Merchant, Total Amount, Date, Category, and individual Line Items.
- Uses resilient heuristic OCR extraction with optional Google Gemini Vision fallback.
- Auto-populates the expense form and recalculates member splits in one click.
- Settle debts instantly via Unified Payments Interface (UPI).
- One-click launch into UPI apps: Google Pay, PhonePe, Paytm, CRED, or BHIM.
- Deep-link format:
upi://pay?pa={upiId}&pn={name}&am={amount}&cu=INR. - Dynamic on-screen QR code preview for settling up on desktop or in-person.
- Copy Payment Link button for sharing over messaging apps.
- Friendly reminders for members who owe you money (
RECEIVABLE). - One-click Remind button copies a polite, formatted settlement message ready to paste into WhatsApp, SMS, or Slack:
"Hey Alex, just a friendly reminder to settle ₹450.00 on Splitzz for Goa Trip!"
- Owner & Member Roles: Group creators retain ownership controls.
- Member Management: Add members by searching email or copying invite links.
- Safe Group Leave: Members can leave anytime once their balance is settled to ₹0.00.
- Ownership Transfer: If the owner leaves, ownership is safely transferred to another active member.
- View net balances (You are owed ₹X or You owe ₹Y) updated instantly.
- Comprehensive activity history logging expense creations, updates, settlements, member changes, and debt simplification toggles.
- One-click export of group expense data into formatted CSV files.
- Includes Date, Description, Category, Paid By, Total Amount, and Member Shares for accounting or archiving.
- Built with Tailwind CSS v4 and Radix UI primitives.
- Native system, light, and dark theme support via
next-themes.
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Framework | Next.js (App Router) | 16.0.10 |
Full-stack React framework with Turbopack |
| UI Library | React | 19.2.1 |
Declarative UI rendering & Server/Client components |
| Styling | Tailwind CSS | v4 |
Utility-first styling with modern CSS variables |
| Component Kit | Radix UI | Latest | Accessible, unstyled headless UI primitives |
| ORM | Drizzle ORM | 0.41.0 |
Type-safe SQL query builder and schema management |
| Database | Neon PostgreSQL | Serverless | Serverless PostgreSQL with connection pooling |
| Authentication | Better-Auth | 1.4.7 |
Secure cookie/session authentication & OAuth |
| State Management | Zustand | 5.0.9 |
Lightweight reactive client store |
| Validation | Zod | 4.2.1 |
End-to-end schema validation |
| Icons & Alerts | Lucide React & Sonner | Latest | Modern icons & toast notification system |
| Testing | Jest & ts-jest | 30.2.0 |
Comprehensive unit and integration test suite |
Splitzz utilizes a relational schema optimized for high concurrency, financial precision (storing cents as integers), and idempotent settlements.
┌────────────────┐ ┌─────────────────┐ ┌────────────────┐
│ user │◀─────▶│ group_members │◀─────▶│ groups │
└────────────────┘ └─────────────────┘ └────────────────┘
│ │
│ paid_by │ group_id
▼ ▼
┌────────────────┐ ┌─────────────────┐ ┌────────────────┐
│ expenses │◀─────▶│ expense_shares │ │ settlements │
└────────────────┘ └─────────────────┘ └────────────────┘
│ │
└────────────────────────┬─────────────────────────┘
▼
┌───────────────────────┐
│ activities │
└───────────────────────┘
user: User accounts with Google OAuth & credential support (id,name,email,image).groups: Expense groups (id,name,description,owner_id,currency,simplify_debts).group_members: Membership join table (id,group_id,user_id, unique composite key).expenses: Group expenses (id,group_id,paid_by,total_amountin cents,description,category).expense_shares: Split shares per member (id,expense_id,user_id,share_amountin cents).settlements: Direct debt settlement records (id,group_id,from_user_id,to_user_id,amountin cents).activities: Audit event stream (id,group_id,user_id,type,metadata).idempotency_keys: Prevents duplicate settlement and expense charge execution on unstable connections.
- Node.js: v18.18 or higher (v20+ recommended)
- PostgreSQL: Local Postgres instance or a free Neon serverless database
- Package Manager:
npm,pnpm, orbun
git clone https://github.com/MilanGohel/splitzz.git
cd splitzz
npm installCreate a .env file in the root directory:
# Database
DATABASE_URL="postgresql://user:password@ep-cool-db.region.neon.tech/splitzz?sslmode=require"
# Better Auth
BETTER_AUTH_URL="http://localhost:3000"
BETTER_AUTH_SECRET="your-super-secret-random-32-char-key"
# Google OAuth (Optional for Google Sign-In)
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
# AI Receipt Scanner (Optional - uses smart heuristic parser if not provided)
GEMINI_API_KEY="your-gemini-api-key"Push the Drizzle ORM schema to your PostgreSQL database:
npx drizzle-kit pushOr generate and run migrations:
npx drizzle-kit generatenpm run devOpen http://localhost:3000 in your browser.
GET /api/groups— List all groups for the authenticated user.POST /api/groups— Create a new group.GET /api/groups/[groupId]— Retrieve group details and members.GET /api/groups/[groupId]/balances— Calculate net balances across all members.GET /api/groups/[groupId]/debts— Retrieve simplified or direct settlement recommendations.PATCH /api/groups/[groupId]/simplify-debts— Toggle debt simplification on or off.
GET /api/groups/[groupId]/members— List members in a group.POST /api/groups/[groupId]/members— Add a member by email or user ID.DELETE /api/groups/[groupId]/members/[memberId]— Remove a member or leave group (requires zero balance).
GET /api/groups/[groupId]/expenses— Paginated list of expenses with optional category and date filters.POST /api/groups/[groupId]/expenses— Create a new expense with custom split shares.GET /api/expenses/[expenseId]— Retrieve single expense details.PUT /api/expenses/[expenseId]— Update an expense and adjust split shares.DELETE /api/expenses/[expenseId]— Delete an expense and restore balances.
GET /api/groups/[groupId]/settlements— List past settlements for a group.POST /api/groups/[groupId]/settlements— Record a debt settlement between two members (idempotent).
POST /api/receipts/scan— Acceptsimageviamultipart/form-dataor JSON base64. Returns extracted merchant, total amount, category, date, and line items.
GET /api/activities— Fetch recent activity events across user groups.GET /api/users/search?q={query}— Search users by name or email for group invitations.GET /api/dashboard— Summary metrics for the user's dashboard.
Splitzz includes a comprehensive test suite covering schemas, API routes, calculation logic, and end-to-end flows.
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run E2E flow tests
npm run test:e2e
# Run with test coverage report
npm run test:coverageCurrent test status: 10 test suites, 120 tests passing.
This project is licensed under the MIT License.