Building a $5k MRR app while freelancing to keep the lights on

Shaun Donnelly, founder of Personal Best

Shaun Donnelly built a hobby project, and he enjoyed it so much that he quit his job to pursue it. It's been a slow burn, but Personal Best is currently at $5k MRR, and he's freelancing to keep the lights on.

Here's Shaun on how he's doing it. 👇

I'm a software engineer in London, UK. I've been a developer for about 15 years, working across a few startups and larger companies. Currently, I contract part-time for a startup, splitting my time between that and indie development.

My main app is Personal Best, a workout tracking app for iOS. It started in May 2020 as a quick hobby project. We were in the COVID lockdowns, and exercising was the only thing getting me out of the house. I only intended to ship a very basic v1.0, but I enjoyed working on it so much that I wanted to continue.

Since then, it has grown to over 500,000 downloads and about 50,000 monthly active users. It's been featured on the App Store multiple times, and it even made a cameo in the WWDC 2026 keynote. I'm close to $5K MRR.

Since it was a hobby project, I didn't do anything to validate Personal Best.

The initial product was basic. It showed your top three workouts of all time, ranked by distance, energy, and time. I built it in about five days, following Paul Hudson's excellent SwiftUI tutorials at hackingwithswift.com.

SwiftUI was brand new then, and I was excited to learn it because its declarative nature aligned with the technologies I used at my day job (React). It was tricky initially because SwiftUI was an immature framework, and it still lacks many features. However, I believe constraints lead to creativity, so I always work around its limitations.

That said, I've enjoyed deleting significant workarounds and replacing them with pure SwiftUI solutions. For example, the code I used to generate custom images from workouts was a total mess. I was very happy once SwiftUI added image generation support.

The only change I've made since 2020 is adding Claude Code to my stack. I use Claude heavily now to write code, but I still review every line of code. I also design every screen and write every line of copy myself — despite what others insist, LLMs are not good at design, and they are even worse at copy. You can always tell when something was written with one.

Personal Best homepage

The main challenge was prioritization and finding time. For Personal Best's first few years, I was full-time employed, and finding time to work on it was really hard. Sometimes, after a busy day at work, the last thing you want is to spend even more time coding — you just want to decompress with a game or movie, or do social things.

I tried many things over the years, but nothing really stuck until I switched to working part-time. That gave me the time I needed, and since then, progress has skyrocketed.

Finding a clear product direction has also been hard. At first, I just added features because I thought they sounded cool or a user asked for them. As a result, the app became a mess with no clear identity, just a collection of unrelated features (think Jira).

I recently defined the app's purpose and have since evolved it in that direction — to be a workout coach benefiting everyone who exercises, whether a marathon runner, a snowboarder, or someone who just walks their dog a few times a week. If I started over, I'd do that upfront.

PB is free to use, with an optional 'Personal Best Pro' membership introduced in late 2020. It's a subscription, and a lifetime option is also available. Pro members get loads of extra stats, heart rate zones, form history, unlimited goals, and some other things.

It's a tricky balance. You want the free tier to be compelling enough that people still use it, but restricted enough that people want to subscribe. I'm still figuring that balance out; most users are on the free tier.

I've run loads of experiments on pricing and trial length, and I will continue to do so as the market and the app evolve.

I made a decision in the beginning that has paid dividends: not having any server-side component; PB runs completely on your phone. This means every subscription is almost 100% profit; I have virtually no marginal costs.

As far as growth, honestly, I've been lucky. I've done almost no paid marketing, so it's all been organic. It was very slow initially, then it picked up pace once I gained Apple's attention and it began featuring on the App Store.

Apple loves it when you adopt their new features or find interesting and novel ways to use their first-party APIs. A good way to get the attention of the editors is to look for opportunities to do that, and then submit a nomination to be featured on App Store Connect whenever you have something notable to share. At the end of the day, the editors are just regular people trying to find compelling stories, so make sure that you give them one.

Other than that, I did some product-led growth, like an image-sharing feature, so you can easily turn your workouts into editorial-quality images to post on social media. Most workout apps offer this now, but I think I was one of the first.

I do have X, Bluesky, and Instagram accounts for the app too, although I no longer use the X one as I don't agree with the worldview of its owner.

And there are little things too. Whenever a user reports a bug, I send them a promo code for a year of the Pro subscription. It's a way to turn a frustrating moment into something nice. And I always ask people to share it with their friends and family if they enjoy it.

Having a community of like-minded people has helped massively. Being indie can be lonely, and you need people to share tips, socialize, and vent with.

A particular shout-out to two people — Rauno and Tai, both lovely people who have helped me with ideas, motivation, and by being good friends throughout.

My advice? Don't get discouraged if things don't take off right away. This is a cliché, but it's true: it's a marathon, not a sprint.

Have good people around you to get you through the dips and to celebrate the peaks with. Be generous with your time and help others out; you might be an indie developer, but you're part of a community, and it's your job to pay it forward and be a force for good in the world.

And lastly, don't be a dick. Don't make things that make the world worse. If you're going to do that, you might as well stick to a corporate job!

Eventually, I plan to work full-time on my apps and stop contracting on the side. I'm not quite there yet, but I'm heading in the right direction.

Check out my blog at codakuma.com, follow me on Mastodon at @shaundon@mstdn.social, and get Personal Best at getpersonalbest.com.

Indie Hackers Newsletter: Subscribe to get the latest stories, trends, and insights for indie hackers in your inbox 3x/week.

Support This Post

Leave a Comment