04
Training App
A self-hosted training app for detailed session logging, week-by-week plans, and a full exercise library, with the pro metrics most free apps hide.
- Full-stack, end to end
- Node.js · Express · MySQL · Sequelize · Auth0 · Docker · nginx · React · Vite · Tailwind CSS
- 800+ exercises
- 18 tables, 49 migrations
- Self-hosted, zero cloud bill
About
A complete training system rather than a session logger: build a plan, run the sessions it prescribes, log what you actually lifted, and review it later.
Plans run over a set number of weeks from reusable templates, and every exercise is prescribed set by set rather than as "3×10": rep ranges, target weight, RPE and RIR, hold durations for timed work, duration and distance for cardio. Weight can be prescribed against your one-rep max, resolved to a real, plate-rounded target the moment a session starts.
The whole thing turns on keeping the prescription and the reality apart. Targets ride into a session as placeholders behind your inputs, so a finished log records both what the plan asked for and what actually happened, and editing that plan months later never rewrites what you already lifted.
Behind it is an Express and Sequelize REST API over MySQL with Auth0 validated on every route, 46 endpoints, and integration tests that run against a real database rather than mocks. Built mobile-first, because it gets used on a phone between sets, and I use it at the gym daily.
Why it exists
To add the functionality I felt was missing from most free training apps. They usually cap how many session templates you can create, and metrics like RIR and RPE often are not even an option. The things that would actually help tend to hide behind a paywall or not exist at all.
The Training App gives you unlimited plan and template creation, detailed logging (RPE, RIR, per-set notes, and weights entered as a percentage of your 1RM), and a full exercise library you can extend with your own movements, all without those limits.
The aim is to make your whole training journey easier and more seamless by giving you everything you need and nothing you do not, in an intuitive way.
What I worked on
Session logging
Log each exercise with sets, reps, weight, per-set notes, and optional RPE and RIR, plus a separate cardio mode that logs duration and distance with pace derived automatically. When a session is started from a plan, its prescribed targets appear as placeholders so you only fill in what you actually lifted (rep ranges like 8 to 12 are supported). Sets check off as you complete them, and each exercise shows what you managed for it last time, pulled from the most recent finished session. A session stays open until you end or cancel it and can be resumed later, and finished sessions can be reopened and edited.
Prescribed vs. actual, everywhere
A plan says what to do; a log records what happened. The two are stored separately at every level: target reps, weight, duration, distance and notes sit alongside the values you enter, per set, per exercise and per session. Targets render as placeholders behind your inputs, so a finished session records both the prescription and how you did against it. Prescribed values are copied onto the log when the session starts rather than read back from the template, so editing a plan months later never rewrites what you already lifted.
Plans and session templates
Build your own plans from reusable session templates, or create standalone templates for one-off sessions, using the exact same builder as a live session. Each template prescribes its target sets, reps, weight (kg or % of 1RM), RPE and RIR per set, along with notes at set, exercise and session level. A plan runs over a set number of weeks and tracks the current week; the dashboard works out the next session from each template's day offset, never before the plan start date, and surfaces a "start today's session" button when it lands on today. Plans and templates can be previewed, edited, and deleted, and deleting a plan day leaves the sessions you already logged from it intact.
Weight as a percentage of 1RM
Prescribe an exercise's weight as a percentage of your one-rep max instead of an absolute number. There's a dedicated screen for managing your 1RMs, with a calculator (estimated from a weight × reps set) and an estimate-from-history option. When a session starts, each percentage is resolved to a real target weight rounded to the nearest 2.5 kg.
Timed exercises
Not everything is reps × weight. A per-exercise Weight / Time / % 1RM toggle lets an exercise log a single hold duration in mm:ss instead, for planks, dead hangs and stretches. It carries from the plan or template into the live session, hides the fields that stop making sense there, and reads back as "1:00 hold" in history.
Want to talk about any of this?
I'm in Oslo. Quickest route is email: I answer within a day.
martin.neset0@gmail.com- Oslo, Norway