Split your expenses easily.
🚀 Try it live at splitty.arkapravo.in — no install needed.
Splitty is a lightweight, self-hostable web app for tracking shared expenses inside a group of people and figuring out the simplest way to settle up. Think of it as a focused, no-frills alternative to apps like Splitwise: you create a group, add the people in it, log who paid for what, and Splitty tells everyone exactly which transfers will leave the group square — using as few payments as possible.
It's built for the small, recurring situations where money gets messy:
- Trips and holidays — someone books the hotel, someone else covers dinner, a third person rents the car.
- Flatmates and roommates — groceries, utilities, that one big delivery, the new vacuum cleaner.
- Friend groups and meetups — one person tabs out at the bar and everyone Venmos them later.
- Couples and families — keeping a running tab on who paid for what without spreadsheets.
If you've ever ended a trip with a screenshot of a Notes-app tally and a vague promise to "sort it out later" — that's the problem Splitty solves.
- Email / password accounts with secure session cookies (JWT via
jose, passwords hashed withbcryptjs). - Expense groups — own and belong to as many groups as you like; Splitty remembers which one you had open last.
- Member management — invite existing users to a group by email; members can leave any group they don't own.
- Expenses — record amount, who paid, who added it, and free-form details. Owners can edit any row; members can edit rows they added or paid for.
- Lockable groups — owners can lock a group when a trip ends, freezing it as read-only.
- Multi-currency — pick from a
currenciestable per group; amounts render with the group's symbol (₹, $, €, …). - Settle up — a greedy minimum-transfer algorithm shows the smallest set of payments that settles the group, and each transfer can be ticked off as paid.
- Profile management — change your name or password, or soft-delete your account.
- Light / dark theme out of the box.
When you open a group's Settle up view, Splitty:
- Sums every expense in the group.
- Divides the total equally among current members to get each person's fair share.
- For each member, computes
balance = paid − share. Positive means they're owed money; negative means they owe. - Greedily pairs the largest creditor with the largest debtor, settles the smaller of the two amounts, and repeats until everyone is within half a cent of zero.
The result is O(n) transfers in the typical case rather than the naive O(n²).
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router, React Compiler enabled) |
| UI | React 19, Tailwind CSS v4, shadcn/ui (base-lyra style), Phosphor Icons |
| Database | Neon serverless Postgres via @neondatabase/serverless |
| ORM | Drizzle ORM + drizzle-kit |
| Auth | jose (JWT) + bcryptjs + httpOnly cookie |
| Notifications | sonner (toasts) |
- Node.js 20+ and npm
- A Postgres database. The defaults assume Neon (the HTTP driver is wired up via
@neondatabase/serverless), but any Postgres reachable via a connection string will work.
npm installCopy the example file and fill in your own values:
cp .env.example .envYou need two variables:
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL |
yes | Postgres connection string. For Neon use the pooled URL with ?sslmode=require&channel_binding=require. |
JWT_SECRET |
yes | At least 32 characters. Used to sign session JWTs. Generate one with openssl rand -base64 48. |
The app throws at startup if JWT_SECRET is missing or shorter than 32 chars.
Drizzle Kit reads DATABASE_URL from .env via dotenv/config.
# Generate SQL migrations from the schema
npm run db:generate
# Apply them to the database
npm run db:migrate
# …or, for quick local iteration, push the schema directly
npm run db:pushSplitty looks up symbols from a
currenciestable at runtime (and defaults new groups toINR). Seed it with at least one row, for example:INSERT INTO currencies (code, symbol, name) VALUES ('INR', '₹', 'Indian Rupee'), ('USD', '$', 'US Dollar'), ('EUR', '€', 'Euro'), ('GBP', '£', 'British Pound') ON CONFLICT (code) DO NOTHING;
Use npm run db:studio to browse and edit data in Drizzle Studio.
npm run devThen open http://localhost:3000, create an account at /auth/sign-up, and you'll land on the home page where you can create your first group.
| Script | What it does |
|---|---|
npm run dev |
Start the Next.js dev server |
npm run build |
Production build |
npm run start |
Serve the production build |
npm run lint |
Run ESLint |
npm run db:generate |
Generate Drizzle SQL migrations from schema.ts |
npm run db:migrate |
Apply pending migrations |
npm run db:push |
Push schema directly to the database (dev only) |
npm run db:pull |
Introspect an existing database into Drizzle schema |
npm run db:studio |
Open Drizzle Studio |
- The Neon HTTP driver works on the Edge runtime, but the routes here explicitly opt into
runtime = "nodejs"to usebcryptjs. If you switch hosts, make sure Node-compatible APIs are available. - Set
DATABASE_URLandJWT_SECRETin your platform's secret manager — never commit.env. RotatingJWT_SECRETinvalidates all existing sessions. - Run migrations (
npm run db:migrate) as part of your deploy pipeline.
Licensed under the GNU Affero General Public License v3.0 — see LICENSE for the full text.
In short: you're free to use, modify, and self-host Splitty, but if you run a modified version as a network service you must make your source available to its users under the same license.