Splint#
Self-hosted expense splitting app.
Features#
- No sign-up required. When you create a ledger you generate a public invite link. Anyone with the link can navigate to the ledger.
- End-to-end encrypted. Ledgers are encrypted and decrypted on the client using the Web Crypto API. The encryption key is generated in the browser and never uploaded to the server.
- Simple, hopefully. The app is shipped as a two-container compose file. I tried to make it easy to install and easy to extend.
- Debt graph visualization. Visually shows the flow of money and who-owes-who, making settlements self-explanatory.
Installation#
Option A: Build from source#
git clone https://splint.git # TODO: URL
cd splint
# Create your .env from the template
cp env/.env.prod.example env/.env
# Edit env/.env — set POSTGRES_PASSWORD and DATABASE_URL
# Build the image
podman build -t splint -f compose/server.Containerfile .
# Start the stack
podman compose -f compose/compose.prod.yml up -d
Option B: Pull pre-built image (I'll get to it in a bit)#
podman pull ghcr.io/asdasdasd/splint:latest # TODO: publish the image somewhere
podman compose -f compose/compose.prod.yml up -d
Splint will be available at http://localhost:3010 (or the port you configured via SPLINT_PORT).
Project structure#
splint/
├── packages/
│ ├── shared/ # Types, E2EE crypto, settlement algorithm
│ ├── server/ # Bun + Hono API + Drizzle ORM (Postgres)
│ └── web/ # React SPA (Vite + React Router)
├── compose/ # Podman Compose files (dev + prod)
│ └── server.Containerfile # Multi-stage production image
├── scripts/ # Build scripts
├── docs/ # Plans and documentation
└── Justfile # Task runner (build, test, deploy, backup)
Tech stack#
- Language: TypeScript
- Runtime: Bun
- Database: Postgres (Drizzle ORM)
- Server: Hono (lightweight web framework)
- Web: React SPA (Vite, React Router, shadcn/ui components)
- Graph viz: graphology + sigma.js
- Containerization: Podman Compose
Development#
See CONTRIBUTING.md for development setup and guidelines.
License#
MIT — see LICENSE.