Case study. Next.js / TypeScript.
PennyTrail
AI-powered expense tracker, zero database
Personal app, no public link
- Role
- Solo: S3 data layer, auth, AI chat, PWA UI
- Status
- In daily usepersonal
- Context
- 2026, personal
- Databases
- 0
- JSON file per year
- 1
- Users (married filing jointly)
- 2
- Infra cost at personal scale
- ~$0

The problem
Tax season for a married-filing-jointly household means reconstructing a year of deductible spending from receipts, bank exports and memory. Off-the-shelf trackers want a subscription, a bank login, or both — and standing up a database plus migrations for two users' worth of JSON-sized data is infrastructure the problem doesn't need.
Architecture
- 1.Capture
- Expense form (PWA)
- Receipt photo
- Category · subcategory
- 2.API routes
- JWT (jose) auth
- CRUD + upload
- CSV export
- 3.S3 store
- expenses/<year>.json
- users · categories JSON
- Receipts · presigned URLs
- 4.Insight
- Recharts dashboard
- GPT-4o streaming chat
- Reads the year's JSON
What it does
A mobile-first, installable PWA for two users tracking IRS-relevant expenses: add, edit and delete with category and subcategory, attach receipt photos, browse by category and year, and export CSV for tax prep. A time-aware dashboard shows monthly bar charts with current-month highlighting and category pie breakdowns.
- Full dark/light/system theming
- Fully customizable categories and subcategories
- In-app user guide and a year selector for multi-year history
Zero-database architecture
All state lives as JSON in S3, partitioned by year (expenses/2026.json), with users.json (bcrypt-hashed) and categories.json alongside; receipt images are served via presigned URLs. For a two-user workload this removes an entire infrastructure tier — no migrations, no connection pools, near-zero cost — while keeping every record trivially portable.
- JWT (jose) auth with httpOnly cookies
- Receipts keyed by expense ID
- User accounts managed by a CLI script — no signup surface
AI spending chat
A GPT-4o chat panel answers natural-language questions about spending — the API route reads the year's expense JSON from S3 and streams the model's answer with that context in-prompt. Quick-action buttons cover the common tax questions.
Mobile-first, 3D-styled UI
- CSS-only card and icon depth effects with a mesh-gradient hero
- Bottom navigation with a glossy floating action button
- Compact expense form tuned for one-handed phone entry
- Every chart via Recharts with SWR data hooks
Stack
- Next.js 16
- TypeScript
- Tailwind v4
- shadcn/ui
- Recharts
- AWS S3
- GPT-4o
- JWT (jose)