Skip to content

Burn Rebuild

A ground-up rebuild of Burn on my own time. I pitched it, we couldn't agree a deal, and it never shipped.

personal project · jul 2025 – jan 2026 · 1,684 commits
Burn Rebuild
1,684commits, jul 2025 to jan 2026
6months, my own time
4apps in one monorepo

Why I rebuilt it

I built the original without AI, and by 2025 the code felt bad to work in. Everything was coupled to everything else, so adding a feature or fixing a bug always came with the worry of breaking something somewhere I wasn't looking.

Agents had just got good enough to move quickly, and I wanted to know what I would build starting over: no inherited debt, everything I had learned since, and the whole system designed rather than accumulated.

The architecture

It's a Clean Architecture monorepo with numbered layers, 1.domain, 2.application, 3.adapters, 4.infrastructure, where imports only ever point inward. The domain layer holds sixteen contexts with no framework anywhere in them: workout, workout-session, program, progressive-overload, challenge, payment, postcard, onboarding and the rest. The adapters layer is interfaces, one per thing the outside world provides: auth, file storage, analytics, error monitoring, and every repository.

Four apps, one repo

What reads as one project is four builds sharing a domain. The React Native client is the face of it and the thing in the screenshots. An Express and tRPC API serves it. A Next.js admin app gives the content and operations side somewhere to work, 58 commits with most of them inside its first week. A Sanity studio holds the content itself.

All four import the same domain and application layers, which is the whole point of arranging it this way: the rules live in one place and each app is a different way in. Turborepo on Bun ties them together, with 149 test files and deploy workflows for staging, production and the admin app.

Why the interfaces

Burn's outside pieces had never stopped moving. Content started on a Strapi backend I built and ended up in Sanity. User data started in Firestore, went into Strapi alongside the content, then came back out into a Postgres database of its own once it was clear that content and users had no business sharing a store. Hosting started on Railway and moved to Fly.io after users on the other side of the world stopped reliably getting their data, which I traced to where the servers were.

Every one of those migrations meant touching code that had no reason to care where the data came from. So the rebuild is interfaces all the way down: an interface for each thing the outside world provides, adapters behind them, dependency injection wiring it together. The domain does not know what is behind it, which turns a provider change into a new adapter instead of a rewrite.

I took it further than it strictly needed to go. By the end I was walking through four layers of abstraction to change one thing, and some of those interfaces were never going to have a second implementation. But the separation is the part I would do again, and it was answering a real problem rather than an imagined one.

Sizing the backend

The other thing I did not understand when I joined Burn was what the backend actually needed to run. I put production on four performance-1x machines on Fly in a blue-green deploy, a great deal more machine than the load ever asked for.

I was two or three years into my career, working to a launch date the business had already built its costs and its marketing around. I did not want it to fall over, and I did not know enough yet to know what enough looked like, so I bought room.

Working out what the rebuild needed is where that finally made sense to me: how much CPU and memory the traffic we actually had called for, how many machines a deploy strategy really implies, what is worth paying for and what is just sitting there. Cost was part of what I pitched, because the rebuild needed a fraction of what I had provisioned for the old one.

What happened to it

I pitched it: finish it, put it in the stores, replace the version that was running. We went back and forth on a deal and never got to one. I stopped in January 2026 and it has never shipped.

Screenshots

active program
workout detail
exercise player
rep logging
rest timer
community