A shared household expense tracker with end-to-end encryption. Built for couples who want to split expenses fairly without exposing their financial data to anyone — including the app developer.
- Upload transactions from CSV/JSON bank exports
- Categorize with drag-and-drop (shared, private, work, exclude)
- AI enrichment — identify merchants and enrich transaction descriptions using Claude
- Monthly settlements — automatically calculate who owes whom
- Auto-categorization — learn from your sorting patterns via merchant rules
- End-to-end encryption — your financial data is encrypted before it leaves your browser
Inspired by Proton Mail, Family Finance implements client-side encryption for core app data so the server never stores your financial records in plaintext.
Your Password
|
v PBKDF2 (600,000 iterations, SHA-256)
Key Encryption Key (KEK)
|
v AES-KW (unwrap)
Data Encryption Key (DEK) — one per household
|
v AES-GCM-256 (encrypt/decrypt)
Stored data — transactions, categories, settlements, names, API keys
What the server can see:
- Email addresses (required for authentication)
- Opaque UUIDs and structural metadata such as timestamps, booleans, sort-order integers, invite state, and limited import bookkeeping
- Deterministic import hashes used for deduplication
What the server cannot see:
- Transaction amounts, dates, descriptions, bank details, notes
- Category names, split types, and split ratios
- Settlement amounts and who owes whom
- Merchant rule patterns
Exceptions to zero-knowledge (plaintext on server):
- Invite preview fields — When creating a household, the creator's name, household name, and avatar are stored in plaintext so the invite page can show who is inviting. These are non-sensitive display hints.
- AI enrichment — If you opt in to AI enrichment, your API key is stored as client-encrypted ciphertext. When you use enrichment, the browser decrypts the key and selected transaction descriptions, then sends them transiently through the Family Finance server to Anthropic in plaintext. Family Finance does not persist those plaintext values. A warning is shown in the UI. Users who prefer full privacy should not use this feature.
Apart from these exceptions, the server is an encrypted storage layer for the app's core data. Filtering, sorting, settlement calculation, and auto-categorization happen client-side in the browser after decryption.
When you create a household and invite your partner:
- A random Data Encryption Key (DEK) is generated in your browser
- The DEK is wrapped (encrypted) with a key derived from your password
- A copy is also wrapped with the invite code (shared secret)
- When your partner joins, they use the invite code to unwrap the DEK and re-wrap it with their own password
- The invite-code copy is deleted — only password-wrapped copies remain
Important: If both household members forget their passwords, all financial data is permanently lost. There is no recovery mechanism. This is a deliberate security trade-off — the same one Proton Mail makes.
All database tables use Supabase Row Level Security (RLS) policies to enforce household-level data isolation at the database level. Error messages are sanitized to never leak database internals.
- Frontend: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS
- UI Components: shadcn/ui
- Database: Supabase (PostgreSQL with RLS)
- Auth: Supabase Auth (email/password)
- Encryption: Web Crypto API (AES-GCM, AES-KW, PBKDF2)
- AI: Anthropic Claude API (user-provided key, encrypted at rest — see note below)
- Drag & Drop: dnd-kit
- Charts: Recharts
- Node.js 20+
- Supabase CLI (
brew install supabase)
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your Supabase URL and keys
# Run database migrations
supabase db push
# Start development server
npm run devNEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key- Sign up — your password becomes your encryption key (a warning is shown)
- Create a household — generates encryption keys, gives you an invite code
- Invite your partner — they join with the code, completing the key exchange
- Upload bank exports — transactions are encrypted in your browser before upload
- Categorize together — drag transactions between columns (shared, private, etc.)
- Settle up — the app calculates the monthly balance and who pays whom