Aukse is a household expense tracker I'm building solo: every line of it, from the React dashboard to the API, the database schema, and the server it runs on.
Why I built it
We tracked our family spending in Excel sheets, and it worked, technically. But entering an expense in a spreadsheet is just uncomfortable enough that you put it off, and a budget you don't update is a budget you don't trust. When I looked for an app to replace it, almost everything was built for personal finance: one user, one pot of money. What we needed was a budget you share with a partner.
So I built it. Two design goals drive the whole product: entering a transaction has to be fast enough that you actually do it, and the overview, budgets, monthly income and expenses, has to be readable at a glance. My family uses it daily, which means I get the most honest QA there is.
The architecture
Aukse is split across four repositories, each with one job:
- aukse-web: the dashboard. React 19 with TypeScript, built with Vite, styled with Tailwind. TanStack Query manages server state; Recharts drives the spending visualisations.
- aukse-api: a Node and Express API in TypeScript. Prisma on PostgreSQL for data, Zod for validation at the boundaries, with OpenAPI documentation generated straight from the Zod schemas, so the docs can't drift from reality.
- aukse-infra: Docker Compose configurations for development and production, plus the nginx reverse-proxy setup. The whole stack runs as containers on a Hetzner Linux server.
- aukse-wp: the marketing site, a custom WordPress theme. For content pages and guides, WordPress is simply the better tool, and after years of building bespoke WordPress themes professionally, it was the fastest path to a good result.
That last repo isn't an accident. Matching the tool to the problem is the way I work: a custom product where the problem is custom, WordPress where the problem is content.
Decisions I'd defend
- A separate SPA and API instead of a full-stack framework. The clean contract between front end and back end keeps both honest, and the API stands alone, ready for a mobile client later without touching the core.
- Clerk for authentication instead of rolling my own. Auth is the highest-risk code in any app that touches money. I'd rather own the domain logic and delegate session security to a team whose whole job it is. Webhooks keep user records in sync with Postgres.
- PostgreSQL and Prisma. Financial data is relational: households, members with roles, accounts of different types, transactions that can be expenses, income, or transfers between accounts. A relational schema with real migrations beats a document store here, and the type-safe client means the database and the TypeScript never disagree.
- Docker and nginx on a Hetzner server I manage, instead of serverless. Predictable cost, no vendor lock-in, and I understand every layer between the code and the user. That knowledge transfers to any team's infrastructure.
Where it stands
The core works and is in daily use: shared households with owner and member roles, multiple account types, expense, income, and transfer tracking, and recurring transactions. It's deliberately not public yet. Before opening it up, I want the boring-but-essential parts done properly: a privacy policy, data export, and the polish an app deserves before strangers trust it with their numbers.
All four repositories are public: aukse-web, aukse-api, aukse-infra, aukse-wp.