
SubTrack
Every subscription on one calendar — with the renewal maths, the multi-currency totals and the reminders all done for you.



Overview
What is SubTrack
SubTrack is a subscription tracker for people who have quietly accumulated more recurring charges than they can name. Streaming, the gym, medical aid, insurance — every subscription lands on one calendar with the renewal maths, the multi-currency totals and the reminders done for you, including free trials that are about to convert. It ships to iOS and Android from one Expo codebase, and it is free.
- Role
- Founder & engineer — designed and built the product end to end: app, API, reminders and release.
- Platform
- iOS · Android
- Stack
- Expo · Next.js · PostgreSQL
- Reminders
- Email + local notifications
- Status
- Live, v1.0.5
- Web
- subtrack.app
Contribution
What I built
- 01Designed the product around one calendar: each subscription's price, cycle and renewal day fold into a month view, a spend dashboard and a list ordered by what charges next — trials about to convert included.
- 02Built the backend as a versioned REST API on Next.js 16 with a 30-day bearer JWT — the Expo app never calls Server Actions, so the contract stays stable across app releases.
- 03Made reminders idempotent: a nightly cron emails renewals and trial conversions through Resend, keyed on a unique (subscription, kind, due date) row, while the app schedules its own local notifications.
- 04Handled money honestly: prices in any currency, one USD rate snapshot a day stored in Postgres and rebased per request — every currency pair resolves without a second upstream call.
- 05Shipped with confidence: 27 Vitest suites on in-memory PGlite, Jest units and a Maestro end-to-end suite; Google, Apple and email sign-in verified against the providers' JWKS.
How it works
How the data moves
The core paths through the system — a dot travels each hop, and the caption says what happens there.
Adding a subscription
From a form to a renewal on the calendar — and reminders armed on the phone.
Swipe sideways to see the whole chart.
new subscriptionYou add a subscription — name, price, billing cycle, renewal day.
Decisions
Calls that shaped it
A versioned REST API, not Server Actions
Server Actions are a web-only protocol. A bearer-authenticated /api/v1 gives the mobile app a contract that survives app-store release cycles.
Reminders on two independent tracks
Email from a cron that is safe to re-run, local notifications from the phone itself — neither depends on the other, and there is no push infrastructure to keep alive.
One rate snapshot a day, rebased on read
A single daily USD snapshot keeps currency conversion cheap and deterministic; any display currency is derived at request time.
Drizzle migrations, PGlite for tests
Generated migrations plus an in-memory Postgres mean the entire backend suite runs without a database server.
Stack
- Expo
- React Native
- Next.js
- TypeScript
- PostgreSQL
- Drizzle
- Resend
- Railway