Skip to content
KH, Kenny Horna, homeEN / ES: Leer en español
Menu
All posts

Published Oct 19, 2026

I built a gym app so I'd keep showing up

My problem with the gym was never the plan. It was consistency and accountability. So I built Spotter, a tiny app that keeps my friends and me showing up.

My friend Andrea trains the way Jeff Nippard teaches: few exercises, done properly, backed by evidence instead of vibes. He’s been at it for a few years already, and it shows. I’ve tried the same approach more than once. It works great, for about two weeks.

The plan was never my problem. Showing up was. So this time I didn’t buy a new notebook. I built an app.

Spotter's header image: a winking kettlebell logo, the line 'A pocket gym coach for beginners', and three phone screens showing the Today view, a Hack Squat exercise card and a rest timer with a new personal record

The problem was never the plan

Every time I quit, it went the same way. I’d open the notes app at the gym, forget what I lifted last week, stand in front of a machine I wasn’t sure was the right one, and lose ten minutes figuring it out. Miss one week and the whole thing felt broken, so I stopped.

My friend Ram wanted to start too: three times a week, before work, in different gyms, with roughly zero gym vocabulary between the two of us. Big trackers like Hevy or Strong are good, but they assume you already know what you’re doing. We didn’t. We needed something that tells you what to do now, at this gym, with this weight, and then gets out of the way.

So I built a spotter

Spotter is a pocket gym coach for a small crew. It’s inspired by the minimal, evidence-based style Andrea follows, it knows what you lifted last time, and it plans each session to fit in about 45 minutes. You open it, it says what’s next.

Spotter's Today screen: session 10 of 36, tomorrow at 07:30 at the Office gym, 7 exercises in about 43 minutes with Ana, a Start button, an RSVP card where Ana is already in, and a streak of 3 weeks in a row

During a session, logging a set is one thumb: weight, reps, and four buttons for how hard it felt. The app works out next week’s weight from that, and lowers it when a set didn’t go well. A rest timer keeps the screen awake, and when you beat your own logbook it makes a small fuss about it:

Spotter in dark mode during a rest: a 2:42 of 3:00 timer, a gold card announcing a new personal record on the Hack Squat at 4 × 75 kg, and the back-off set up next

It also knows your gym without you typing it in. When you meet a machine, you can take one photo and a small vision model answers a very narrow question: is this the machine I’m supposed to use, one of the two named substitutes, or something else? That costs about $0.0004 per photo. I’d still rather tap “Yes, I found it”, which the app now allows, but it’s there when I’m standing in front of something that looks like a medieval torture device.

Consistency over kilos

The part I care about most is the crew. You can train with friends in person, or virtually, at your own times, and still see each other show up. You get a feed, cheers, and the occasional nudge.

The Office crew feed in Spotter: cards for Kenny, Ana and Leo each finishing an Upper session in 46 minutes with personal records, and Cheer buttons under the ones not cheered yet

A few rules came out of that:

  • The board never shows kilos. It compares who showed up, not who lifts more. I’m not saying that to protect myself (fine, a little).
  • The streak forgives a missed week. One bad week was exactly what used to end it for me.
  • No guilt pushes. If you disappear for a while, the app welcomes you back. It never sends a “we miss you”.

Life moves sessions, too. Changing the day or time takes two taps, the rest of the week stays where it was, and your crew sees that you moved:

Spotter's change-day sheet for a Full body session on Tuesday 20 October at 07:30: a two-week calendar with Wednesday 21 selected, time options, a note that the Upper session stays on Thursday and Ana sees the move, and a button to move it to Wednesday

Who actually built it

I didn’t write the code. More interesting: neither did the agent in charge.

I ran Claude Code as a lead developer. It planned the work, wrote a brief for every piece, sent each one to a specialist agent, made the product calls I didn’t need to make, and reviewed what came back. The plan lived in a doc plus a Solo scratchpad and todo list. Every lane got a brief file with the paths it owned, what to deliver, which tests to write, and where to report.

The lanes ran in parallel, each in its own git worktree, and the workers weren’t allowed to touch git at all. A separate integrator agent applied each patch, resolved conflicts, ran every check and committed. The bigger, more expensive model handled the hard parts, like the progression engine and the reviews, and a cheaper one got the mechanical work, like copy passes and small fixes. Same logic as not hiring a senior engineer to rename buttons.

It went in waves: the foundation first, then the actual product, then the deeper features (machine matching, progression, the crew board, push reminders), then several rounds of review and fixes, then production. One of those rounds ran overnight without me. Timers woke agents back up when they hit rate limits or network errors, and by morning the lead had merged two review reports into five new lanes on its own. I woke up to work that was already in progress. Usually it’s the other way around.

The reviewers earned their keep

Tests catch broken code. Reviews caught the wrong ideas. I had the lead bring in expert reviewers, each with a narrow job:

  • A code reviewer found four blockers. The best one: timestamps stored two hours early. For a 7:30 session, that’s just cruel.
  • A mobile UX expert went through all 67 screenshots and ranked ten changes. One line of “homework” before the first session wasn’t tappable, so day one turned into seven learning screens plus seven find-the-machine screens in the middle of the workout.
  • A training-science reviewer checked the engine against the method. The app never lowered the weight after a failed set, and it estimated 54 to 57 minutes for sessions that really take about 42.
  • An engagement expert found that the last session of the program was a dead end, with no second run, and that missing a single week reset the streak. Which was precisely my old problem, now in software.

When reviewers disagreed, the lead decided and wrote down why. A final acceptance review then ran the whole crew journey in a browser and gave a go or no-go. It said go.

Me, from the gym floor

My job was product owner, mostly from my phone between sets. Buttons that overflowed. A header that jumped. A demo image that was too small to see. “Why do I need a photo if I already found the machine?” Each comment turned into a lane within minutes.

The logo took three rounds. The first was a flexed arm, rejected because it looked like something else. The second was a lineup of muscles, fists and kettlebells with faces. The third stuck: a winking kettlebell, ink on lilac. It has since become the mascot, with seven moods.

The numbers, for the record

  • About 3 days, from October 16 to 19.
  • About 300 commits.
  • About 1,300 Pest tests and 170+ Vitest tests, all green, with static analysis at its strictest level and zero errors.
  • Laravel, Inertia and React, SQLite, and a PWA that logs sets offline when the gym basement has no signal. Deployed with Laravel Forge behind Cloudflare. In English and Spanish, the Peruvian kind.

It’s a tiny, private app for me and a few close friends: free, invite-only, no ads. If you’re curious, there’s a public landing page, but you can’t sign up.

What I take from it

Three days got us an app. The app doesn’t lift anything. Andrea didn’t need any of this to show up, and I did, so I built the thing that removes every excuse I used to have: what to do, where the machine is, what I lifted last time, and who’s going to notice if I don’t come.

Whether it works, ask me in three months. For now, the streak says three weeks in a row. The demo data says that, anyway.

Spotter is an independent personal project, not affiliated with or endorsed by Jeff Nippard.