Back to projects
Own product·Solo Developer·2026

Pesä

Give every euro a home

19
API routes
13
database tables
2
languages (fi/en), 273 keys

Problem

Budgeting apps budget through the rear-view mirror: they show where money went, not where it should go. And the tool that matters most to someone in debt — interest-aware, planned payoff — is missing from them entirely.

Solution

01

The "salary arrived" ritual

No background bank polling. When income lands, the user opens one sheet and allocates the money into envelopes — five minutes that buy control of the whole month.

02

Debt avalanche, to the cent

The allocator splits the monthly pool across debts so the sum always matches exactly: minimums first, surplus to the focus debt, shortfalls resolved with a deterministic largest-remainder split. The invariant is unit-tested.

03

Double-entry bookkeeping

A debt payment writes two linked transactions — out of the account, into the debt — and draws down the linked envelope at the same time. An interest-aware projection tells you when the debt is gone, and refuses to project if the payment can’t even cover interest.

04

A backend without a backend

Expo Router API routes handle the server side: the same +api.ts files serve the native app and the web. Neon Postgres + Drizzle, auth via token (native) and cookie (web) — one auth model, two transports.

Gallery

Pesä — sign in: "give every euro a job"
Pesä — sign in: "give every euro a job"

Highlights

Ready-to-Assign computed in one SQL expression — debt accounts can’t leak into it
Money always as integer cents — no floating-point errors
Six target cadences + by-date targets ("needed this month")
Personal debts in both directions (I owe / owed to me)
Localized starter budget (fi/en category trees)

Stack

App
ExpoReact NativeExpo Router API routes
Data
Neon PostgresDrizzle ORMBetter Auth
Quality
TypeScript strictZodnode:test

Want one like this?

Tell me about your project — I usually reply the same day.