Case study
Building Theron — gym management software
A gym and personal-training platform I designed, built and shipped on my own: the back office a gym runs on, and the app its members use.
Open theronapp.comThe problem
Small gyms and independent trainers run on a spreadsheet and a notebook. The data is all there — who is a member, what they pay, when their membership ends, what they lifted last week — but it is in a shape nobody can ask a question of. Nobody knows how many members are due to renew this month without opening the file and counting.
The commercial platforms that solve this are priced and scoped for chains, and most of what they charge for is the part a twenty-member studio does not have: door access hardware, point of sale, sales pipelines, marketing automation.
What I built
Theron is two products against one database. The back office is a gym management system — members, plans, renewals, and the programmes a trainer assigns — and the member app is where clients log workouts and track macros, including by photographing a meal.
The reporting side was the reason to build it at all. The retention view answers who is due to renew, who lapsed, and what that cost, and the revenue panel breaks income down by month and by plan. The client records hold history rather than a current snapshot, so progress is something you can look at over time instead of something you remember.
What it deliberately does not do matters as much. It is not a booking calendar, it does not sell memberships at a counter, and it does not run marketing campaigns. The full feature breakdown says so explicitly, including the rows where the answer is no.
How it is built
The member app is React Native on iOS and Android. The marketing site and the operator dashboard are one Next.js App Router codebase, which keeps the public pages and the authenticated product on the same deploy and the same types.
Supabase provides Postgres, auth and row-level security. Every table a gym touches is scoped by organisation at the database level rather than in application code, because a bug in a query should not be able to leak one gym's member list to another. Billing runs on Stripe, and the entitlement gates are read from one shared module so the pricing page and the server checks cannot drift apart.
Food recognition came out of my MSc thesis — a multi-task ResNet50 in PyTorch doing classification and weight regression on a custom-labelled dataset of 47 categories — which is what made a photo-based macro log realistic rather than a demo.
What I learned
Shipping alone means the boring decisions are the expensive ones. Two paid for themselves repeatedly: keeping a single source of truth for anything the product charges for, and writing the honest "we don't do this" list early, because it settles the scope arguments you have with yourself at two in the morning.
The product is live and public, and the pricing is on the site rather than behind a sales call: theronapp.com/pricing.