Why I built my own running app
I started running again at 41, hated paying a subscription to see my own data, and decided to build the app I actually wanted. Here is where it started.

In February this year I started running again. To be fair, it was my wife who nudged me into it. I am 41, I live in Lieboch just outside Graz with my wife, our three kids, and our small zoo (a dog, two cats, and three tortoises), and somewhere in there I had quietly stopped being someone who runs.
What actually got me out the door was a training group, the "Liebocher Lauf-Team", that meets every Tuesday after work. Honestly, getting the routine going was tough. My work schedule was relentless and the easiest thing in the world would have been to skip it. But a fixed time on a fixed day, with people expecting you, is a completely different kind of commitment than a vague plan to "go for a run sometime." That standing Tuesday slot is the reason I stuck with it and slowly started running regularly again, chasing speed and endurance back week by week. So a genuine thank-you to my wife, and to everyone in the Liebocher Lauf-Team, for making it happen. This app exists partly because you did.
What I did not expect was that the running would turn into a software project.
The apps were not the problem. The deal was.
I tried the usual suspects. They are good apps, genuinely. But two things wore me down.
The first was customizability. I wanted to decide what my watch shows me while I run, where, and how big. Most apps hand you a fixed set of screens and a take-it-or-leave-it layout. I did not want to negotiate with someone else's idea of what a "running screen" should be.
The second was the deal. To see my own data, properly, I was expected to subscribe. Another monthly line item, forever, for numbers my own watch measured. I do not think that is fair. I think a one-time purchase for an app is fair: you pay once, you own it, and I keep updating it for as long as I reasonably can. If there is ever a big enough leap, maybe there is a version 2 at a new price. But that is a bridge for later. We will see how it goes.
Privacy is not a feature. It is the default.
I care about this more than is fashionable. I believe in the GDPR, not as a compliance checkbox but as the right idea: you collect the data you actually need, and nothing else. For Runara, today, "the data I actually need" is none. The app collects nothing. No account, no cloud, no analytics on your training. Your workouts live in Apple Health, on your devices, where they belong.
I will be honest and not promise that this never changes. If a future feature genuinely needs something, I will say so, plainly, and you will get to choose. But the starting point is zero, and I intend to keep the bar that high.
So I built the thing
I am an engineer by background, and I built Runara with a lot of help from Claude. I want to be upfront about that, because "AI-built app" has become shorthand for cheap and broken. This is not that. I treated Claude like a very fast, very well-read pair-programmer, and I brought the judgment: the architecture decisions, the taste, the "no, that is wrong, here is why." More on that honest accounting in the final post of this series.
The first day set the tone. Before a single screen existed I had a strict project skeleton: a Swift package called SportsKit so the watch app would not drag along iPhone-only dependencies, a CI pipeline with an 80 percent test-coverage gate, self-hosted fonts (Archivo Narrow for the big numerals, JetBrains Mono for anything tabular), and Swift 6's strict concurrency turned all the way up. Instrument-grade discipline from commit zero, because retrofitting quality never works.
It was not all clean. The very first follow-up commit was a bug fix:
fix(phase-0): bundle OFL fonts end-to-end (subset API + resource layout)
The font-subsetting tool I wrote called a method that did not exist. A fitting start: the very first thing I built was already broken, and the very first thing I did was fix it and move on. That is most of software, honestly.
A rule that saved me later
One early decision looked like paranoia at the time and turned out to be the thing that saved real data. Every piece of information that gets stored on disk or synced between the watch and the phone has to survive being read back by a newer version of the app that has since grown new fields. Swift's automatic decoding does not do this gracefully. So I made it a hard rule: every stored type gets hand-written decoding that tolerates missing fields.
Weeks later that exact rule was the difference between "the app gained a feature" and "the app silently erased everyone's settings." I will tell that story properly in the Apple Health post. For now: the boring foundations are the ones that matter.
What this series is
This is the build log. I am going to walk through how Runara actually got made, in order, including the parts that did not go well. The map feature that fought me for a day. The tiny watch icon that took three tries to stop looking broken. The crash that took an on-device debugger and three attempts to kill. A pool in my garden that turned into a real feature.
It was a focused, intense couple of weeks of building, on top of a full life. I am proud of it, and I want to show you the seams. That feels more honest than a glossy launch post, and frankly it is a better story.
Next up: getting real numbers onto the wrist, and teaching the watch to draw a map where there is no signal at all.