Ironform: Strength Training System

Ironform

Ironform: A Powerlifting App That Had to Be Rebuilt When My Own Program Outgrew It

Ironform started as a 5/3/1 tracker I built in Bolt.new to replace my training spreadsheet, tested in public on Reddit, then rebuilt from the architecture up with Claude as a coding partner when I switched to the Juggernaut Method and the app's core assumptions no longer held. It is a full-stack progressive web app I designed and built alone: wave scheduling that fits a real meet date, training maxes that update from performance instead of a calendar, and a weak-point-driven accessory system. It replaced my spreadsheet entirely and is used by two athletes, including me, with a meet-day flow that has already been used at a real competition.

Key Approach:

  • Self-directed problem identification: no brief, no assignment, just a gap I kept running into

  • Built and validated in public: prototyped in Bolt.new, posted early to Reddit for feedback, then rebuilt with Claude when the program itself changed

  • Purpose-built design system with documented anti-references and a single-accent-color constraint

  • Full program logic implemented from scratch: wave scheduling, meet-date fitting, RPE-regulated back-off sets

  • Accessibility-first: custom components throughout, WCAG 2.1 AA, 44px minimum touch targets

  • Built for real in-session use: chalk-dusted hands, phone at arm's length, fluorescent gym lighting

THE PROBLEM

When a spreadsheet stops working

I train for competitive powerlifting. For years I ran my programming in a spreadsheet: percentages, wave schedules, projected maxes, all of it typed in and recalculated by hand every week. It worked at a desk. It did not work standing at a rack with chalk on my hands, trying to find one number in a sheet built for scrolling and squinting, not for a thirty-second rest period.

The gap no one filled

I looked for an app that handled this the way I actually train, with real periodization logic instead of a flat percentage calculator. Nothing did. Every consumer fitness app treated a structured program as a static lookup table, so I decided to build the tracker I actually needed.

THE PROBLEM

When a spreadsheet stops working

I train for competitive powerlifting. For years I ran my programming in a spreadsheet: percentages, wave schedules, projected maxes, all of it typed in and recalculated by hand every week. It worked at a desk. It did not work standing at a rack with chalk on my hands, trying to find one number in a sheet built for scrolling and squinting, not for a thirty-second rest period.

The gap no one filled

I looked for an app that handled this the way I actually train, with real periodization logic instead of a flat percentage calculator. Nothing did. Every consumer fitness app treated a structured program as a static lookup table, so I decided to build the tracker I actually needed.

THE PROBLEM

When a spreadsheet stops working

I train for competitive powerlifting. For years I ran my programming in a spreadsheet: percentages, wave schedules, projected maxes, all of it typed in and recalculated by hand every week. It worked at a desk. It did not work standing at a rack with chalk on my hands, trying to find one number in a sheet built for scrolling and squinting, not for a thirty-second rest period.

The gap no one filled

I looked for an app that handled this the way I actually train, with real periodization logic instead of a flat percentage calculator. Nothing did. Every consumer fitness app treated a structured program as a static lookup table, so I decided to build the tracker I actually needed.

RESEARCH AND DISCOVERY

Understanding the Gap

Apps like Strong, Hevy, and JEFIT offer solid general tracking, but none of them implement structured periodization with real program logic. They treat a percentage-based program as a static calculator: you enter a max, they return a number, and when a realization week changes your training max you update everything by hand.

JuggernautAI was the one app that came close. It requires a paid subscription and treats the program as a black box, with no visibility into how the schedule is calculated or why.

That mattered to me more than convenience. I know the Juggernaut Method well enough to want to see exactly what the app is computing and confirm it is right, not just trust a number it hands me.

Design principles

  • Every element serves a training decision. If it doesn't help the athlete know what to lift, when, or how much, it doesn't belong.

  • Numbers are shown because they're needed, not because they look impressive.

  • Tone is direct and assured, never hyped. The app has done the math; it doesn't need to celebrate itself.

  • Designed for chalk-dusted hands mid-session. Touch targets are generous, states are unambiguous, nothing requires careful reading.

  • Correctness first, aesthetics second.

DESIGN SOLUTION

Program logic as the core feature

I designed Ironform around a single question: what does a competitive powerlifter need to walk into the gym, know exactly what to lift, log it, and leave?

Orientation at a glance

The home screen answers four questions before an athlete does anything: what lift is today, what wave and phase they're in, and how many weeks remain until their meet. A week navigator lets an athlete preview upcoming training without leaving the screen, and projected maxes update automatically as the program advances.

The home screen answers four questions before an athlete does anything: what lift is today, what wave and phase they're in, and how many weeks remain until their meet. A week navigator lets an athlete preview upcoming training without leaving the screen, and projected maxes update automatically as the program advances.

The multi-step session flow

Each session moves through a structured flow: warm-up progression, main lift, accessories, complete. Main lift sets, reps, and percentages pull directly from the current wave and phase, and the realization week surfaces an RPE selector that calculates back-off sets from the top set in real time.

Each session moves through a structured flow: warm-up progression, main lift, accessories, complete. Main lift sets, reps, and percentages pull directly from the current wave and phase, and the realization week surfaces an RPE selector that calculates back-off sets from the top set in real time.

Program variations & weak points

The original design used simple program variations: BBB, BBS, Standard. I scrapped it once I realized the real variable wasn't training volume style, it was where a lifter was losing the lift. A lifter who fails squats at the bottom needs different accessory work than one who fails at lockout. The current system lets users tag sticking points per lift, and the app selects a mix of one to two weak-point-targeted exercises and two to three general support movements automatically per session.

The original design used simple program variations: BBB, BBS, Standard. I scrapped it once I realized the real variable wasn't training volume style, it was where a lifter was losing the lift. A lifter who fails squats at the bottom needs different accessory work than one who fails at lockout. The current system lets users tag sticking points per lift, and the app selects a mix of one to two weak-point-targeted exercises and two to three general support movements automatically per session.

PROCESS & ITERATION

Architecture that earned a rewrite

I started with the program I was running at the time, 5/3/1, and built a minimal tracker: enter your maxes, get your sets for the week, log the session. I built that first version in Bolt.new, which let me go from an idea to something live and shareable in days, and that speed is what made it realistic to put an early version in front of strangers instead of just planning to. I hosted it publicly at 531workouttracker.bolt.host and posted it to r/531Discussion for feedback, because I wanted real strangers' opinions, not just my own sense that it was working.

What public feedback changed

The feedback was mixed and useful in different ways. One commenter argued no app could beat a free spreadsheet and that I would never get anyone to pay for this; I agreed with the first half and told them the second half was never the point, since this was a personal project I was building to use myself. Another reader gave a detailed list I actually acted on: let users pick which plates their gym stocks, fix a unit bug that read a kilogram bodyweight as an elite Wilks score, and let a lifter redo a session after a bad day instead of blocking it outright. The plate fix shipped.

PROCESS & ITERATION

Architecture that earned a rewrite

I started with the program I was running at the time, 5/3/1, and built a minimal tracker: enter your maxes, get your sets for the week, log the session. I built that first version in Bolt.new, which let me go from an idea to something live and shareable in days, and that speed is what made it realistic to put an early version in front of strangers instead of just planning to. I hosted it publicly at 531workouttracker.bolt.host and posted it to r/531Discussion for feedback, because I wanted real strangers' opinions, not just my own sense that it was working.

What public feedback changed

The feedback was mixed and useful in different ways. One commenter argued no app could beat a free spreadsheet and that I would never get anyone to pay for this; I agreed with the first half and told them the second half was never the point, since this was a personal project I was building to use myself. Another reader gave a detailed list I actually acted on: let users pick which plates their gym stocks, fix a unit bug that read a kilogram bodyweight as an elite Wilks score, and let a lifter redo a session after a bad day instead of blocking it outright. The plate fix shipped.

PROCESS & ITERATION

Architecture that earned a rewrite

I started with the program I was running at the time, 5/3/1, and built a minimal tracker: enter your maxes, get your sets for the week, log the session. I built that first version in Bolt.new, which let me go from an idea to something live and shareable in days, and that speed is what made it realistic to put an early version in front of strangers instead of just planning to. I hosted it publicly at 531workouttracker.bolt.host and posted it to r/531Discussion for feedback, because I wanted real strangers' opinions, not just my own sense that it was working.

What public feedback changed

The feedback was mixed and useful in different ways. One commenter argued no app could beat a free spreadsheet and that I would never get anyone to pay for this; I agreed with the first half and told them the second half was never the point, since this was a personal project I was building to use myself. Another reader gave a detailed list I actually acted on: let users pick which plates their gym stocks, fix a unit bug that read a kilogram bodyweight as an elite Wilks score, and let a lifter redo a session after a bad day instead of blocking it outright. The plate fix shipped.

The rewrite

The bigger rebuild came from my own training, not from that feedback. I moved from 5/3/1 to the Juggernaut Method, and 5/3/1's fixed weekly increments no longer matched how I was actually progressing. It is also where I moved off Bolt.new and started working directly with Claude as a coding partner instead of a builder tool. A wave-scheduling engine, a training-max formula, and a weak-point accessory system needed changes I could read, question, and revise line by line, not accept wholesale from a tool optimized for speed over precision.

Revamped chart design with clear waves and tooltips with top sets

The rewrite

The bigger rebuild came from my own training, not from that feedback. I moved from 5/3/1 to the Juggernaut Method, and 5/3/1's fixed weekly increments no longer matched how I was actually progressing. It is also where I moved off Bolt.new and started working directly with Claude as a coding partner instead of a builder tool. A wave-scheduling engine, a training-max formula, and a weak-point accessory system needed changes I could read, question, and revise line by line, not accept wholesale from a tool optimized for speed over precision.

Revamped chart design with clear waves and tooltips with top sets

The rewrite

The bigger rebuild came from my own training, not from that feedback. I moved from 5/3/1 to the Juggernaut Method, and 5/3/1's fixed weekly increments no longer matched how I was actually progressing. It is also where I moved off Bolt.new and started working directly with Claude as a coding partner instead of a builder tool. A wave-scheduling engine, a training-max formula, and a weak-point accessory system needed changes I could read, question, and revise line by line, not accept wholesale from a tool optimized for speed over precision.

Revamped chart design with clear waves and tooltips with top sets

The code audit

After the Juggernaut rewrite the codebase showed the scars of building fast against a moving program. I went back through it deliberately: extracted shared UI components that had been copy-pasted across pages, removed dead code and stale docs, and pulled duplicated logic into shared utilities. Nobody asked me to do that pass. I did it because a project I keep coming back to needs to survive its own iteration, not just accumulate it.

Screenshot of Github repo with historical commit messages

The code audit

After the Juggernaut rewrite the codebase showed the scars of building fast against a moving program. I went back through it deliberately: extracted shared UI components that had been copy-pasted across pages, removed dead code and stale docs, and pulled duplicated logic into shared utilities. Nobody asked me to do that pass. I did it because a project I keep coming back to needs to survive its own iteration, not just accumulate it.

Screenshot of Github repo with historical commit messages

The code audit

After the Juggernaut rewrite the codebase showed the scars of building fast against a moving program. I went back through it deliberately: extracted shared UI components that had been copy-pasted across pages, removed dead code and stale docs, and pulled duplicated logic into shared utilities. Nobody asked me to do that pass. I did it because a project I keep coming back to needs to survive its own iteration, not just accumulate it.

Screenshot of Github repo with historical commit messages

RETROSPECTIVE

Outcome

Ironform is live. Wave scheduling, training max updates, warm-up progression, RPE-based back-off sets, and the weak-point accessory system are all live and driving real training weeks, not just demoed. The meet-day flow, which only appears within a day of an athlete's actual competition, has already been used at a real meet: it logged the attempts and auto-updated the training max from the PR to drive the next cycle correctly. Ironform is what happens when nobody assigns me the problem. I noticed something broken in my own training, shipped a version good enough to put in front of strangers, took the feedback that actually mattered, and rebuilt the architecture when the thing driving the product changed underneath it. Building alone, choosing the right tool for each stage instead of defaulting to one, and going back to hold a growing codebase to a higher bar than it started with is the part a professional case study rarely gets to show, because the scope, the team, and the tooling are usually already decided for you.

What I’d do differently

If I were starting over I would design onboarding around meet date and sticking points from day one instead of retrofitting them in later. I also would validate the wave-scheduling logic with other Juggernaut athletes sooner instead of relying only on my own understanding of the program, and I would have held the accessory system open rather than shipping a placeholder Standard/BBB/BBS picker I already suspected was wrong.

RETROSPECTIVE

Outcome

Ironform is live. Wave scheduling, training max updates, warm-up progression, RPE-based back-off sets, and the weak-point accessory system are all live and driving real training weeks, not just demoed. The meet-day flow, which only appears within a day of an athlete's actual competition, has already been used at a real meet: it logged the attempts and auto-updated the training max from the PR to drive the next cycle correctly. Ironform is what happens when nobody assigns me the problem. I noticed something broken in my own training, shipped a version good enough to put in front of strangers, took the feedback that actually mattered, and rebuilt the architecture when the thing driving the product changed underneath it. Building alone, choosing the right tool for each stage instead of defaulting to one, and going back to hold a growing codebase to a higher bar than it started with is the part a professional case study rarely gets to show, because the scope, the team, and the tooling are usually already decided for you.

What I’d do differently

If I were starting over I would design onboarding around meet date and sticking points from day one instead of retrofitting them in later. I also would validate the wave-scheduling logic with other Juggernaut athletes sooner instead of relying only on my own understanding of the program, and I would have held the accessory system open rather than shipping a placeholder Standard/BBB/BBS picker I already suspected was wrong.

RETROSPECTIVE

Outcome

Ironform is live. Wave scheduling, training max updates, warm-up progression, RPE-based back-off sets, and the weak-point accessory system are all live and driving real training weeks, not just demoed. The meet-day flow, which only appears within a day of an athlete's actual competition, has already been used at a real meet: it logged the attempts and auto-updated the training max from the PR to drive the next cycle correctly. Ironform is what happens when nobody assigns me the problem. I noticed something broken in my own training, shipped a version good enough to put in front of strangers, took the feedback that actually mattered, and rebuilt the architecture when the thing driving the product changed underneath it. Building alone, choosing the right tool for each stage instead of defaulting to one, and going back to hold a growing codebase to a higher bar than it started with is the part a professional case study rarely gets to show, because the scope, the team, and the tooling are usually already decided for you.

What I’d do differently

If I were starting over I would design onboarding around meet date and sticking points from day one instead of retrofitting them in later. I also would validate the wave-scheduling logic with other Juggernaut athletes sooner instead of relying only on my own understanding of the program, and I would have held the accessory system open rather than shipping a placeholder Standard/BBB/BBS picker I already suspected was wrong.

Featured Case Studies

Featured Case Studies

Bridging the Gap in Strategic Planning with ProductPlan

Driving strategic alignment with 54% month to month retention boost with portfolio visualizations

Curriculum Management for School and District Admins

Increasing Daily Active Usage by 15% through optimization of curriculum management

Streamlining Product Development to Reduce Workflow Fragmentation

Achieving a 27% Increase in User Engagement through Streamlined Product Development

Let's build something worth reading about.

Thank you for your interest in my work. Let’s connect!