Building HelioPeak: lessons from indie iOS development
A few months of evenings and weekends, six languages, three platforms, one developer
This is the last article in this series, and it is the one with the smallest claim to general utility. The previous fourteen articles were about solar, about PVOutput, about monitoring, about the practical questions of running a residential PV system. This one is about building a small piece of software for that audience, by one person, over the course of a few months of evenings and weekends. If you have been reading along for the technical content, you can stop here; nothing in this article will affect how your panels produce kilowatt-hours. If you have ever thought about building something small for a niche audience and wondered what that actually looks like in 2026, this article is for you.
I will be honest about the choices I made, the mistakes I made, and the parts of the work that surprised me. The goal is not to argue that anyone should do what I did. It is to describe what doing it looked like, for one specific project.
Why build another solar app at all
The first question, the one that should have stopped me at the start and almost did, was whether the world needed another PVOutput app for iOS. We covered the landscape in Solar monitoring on iOS: comparing the options in 2026: there were already three serious options on the App Store, each with its constituency, each maintained by someone who cared about the problem. The honest case for a fourth app was thin.
What pushed me forward was an observation about my own daily reading habit. The existing apps were each excellent at something specific, but none of them was the app I actually wanted to open every morning. One had a beautiful animated power flow but visual design that felt like it predated SwiftUI. One was simple and reliable but missing the multi-year analysis I cared about. One was actively developed but missed my language. There was no app that combined modern native design, deep historical analysis, all three Apple platforms, and the long-term ownership view that comes from watching the same panels season after season.
This is the indie developer's eternal trap: noticing a gap in a market that is small to begin with, and deciding to spend several months filling it. The economic argument was never strong. The personal argument, wanting the tool to exist, mostly for myself, was what carried me through the first couple of weeks. I suspect this is true of most indie projects in mature markets. You build what you want to use, and you hope enough other people share your taste.
The starting point: not a Swift developer
I have a long IT background, systems, infrastructure, architecture, the parts of the technology stack that are several layers below the user interface. I had not written a Swift application before this project. I had not used SwiftUI. I had not navigated Xcode in any serious way. I had built command-line tools, automation scripts, infrastructure-as-code, web services, the things that an IT person picks up over a career. I had not built a polished native app for a consumer platform.
This sounds like an obvious obstacle to building a polished native iOS app. In a different decade it would have been a fatal one. In 2026 it is a manageable one, for two reasons.
The first reason is that Apple's developer ecosystem has become remarkably approachable for someone coming from adjacent disciplines. SwiftUI is, by the standards of native UI frameworks, an unusually clean and learnable system. The documentation is thorough. The simulator works well enough to develop without constant device testing. The toolchain is free. The information needed to build a competent app, for someone with general programming literacy, is all available without specialised training.
The second reason is that AI coding assistants have changed the leverage available to a single developer. I will not dramatise this; I think the breathless coverage of AI tooling has done its share of harm to honest conversations about it. But the practical reality is that an AI assistant, used carefully, lets a non-Swift-developer produce code that is closer to idiomatic SwiftUI than they could have produced solo, and lets them spot patterns and architectural choices that would otherwise require years of platform experience to recognise. I used Claude throughout this project, reviewing every piece of generated code against my IT instincts and the documentation, treating it as a senior collaborator rather than a magic wand. The result was an app that I could not have built alone in any reasonable timeframe, and that I am responsible for understanding and maintaining. That is the model that worked for me; I think it is also the model that will work for most indie developers building niche tools in the next few years.
What the actual work looked like
The total development time for HelioPeak, by my rough counting, is several months of evenings and weekends rather than full-time effort. It is sometimes a few hours in an evening, sometimes a long weekend, sometimes a multi-week gap because life or the consulting business got in the way. It is not full-time work. It is the project that runs on the side of an existing consulting business.
The first three weeks were just getting to a build that ran and showed something useful from PVOutput. The PVOutput API is straightforward but has a few non-obvious quirks (the 149-record cap on getoutput.jsp, the rate limit asymmetry between free and donor accounts, the way getstatistic returns dates) that took some discovery work. Most of that early time was data plumbing and basic SwiftUI scaffolding, not anything you would call interesting.
By week 4, the basic dashboard was working. By week 5, the charts were good enough to look at daily. By week 6, there was something that could plausibly be called a beta. The first version that went to Apple for review was rejected. The second version made it through. The first paid user appeared a week after launch. By the end of the second month the app had multi-system support, six languages, an annual report PDF, widgets, Notes, an iCloud sync layer, and the architectural foundations for the things still on the roadmap.
Looking back, the part of the work that took the most time was not the part I expected. Building features goes faster than you think. Polishing them takes longer than you think. The last twenty percent of any feature, the empty state when there is no data, the loading state when the API is slow, the error state when the network fails, the accessibility labels, the localised strings for six languages, the iPad layout that needs to be subtly different from the iPhone layout, these collectively consume more time than the original feature build did. I did not appreciate this until I was a few cycles in.
Six languages from day one
The decision to localise into six languages from the first public release was made early and never quite justified by data. The argument was simple: the audience for a PVOutput app on iOS is mostly European, Europe is multilingual, and an English-only solar app would feel parochial to a Dutch or German user. The argument against was equally simple: localising into six languages on a first release is a lot of work for an audience that does not yet exist.
I localised anyway, and I am still glad I did. The user base that emerged in the first weeks was indeed European, and a meaningful fraction of it was reading the app in Dutch, French, or German rather than English. The Italian and Spanish localisations have produced smaller user bases but real ones. The cost in initial development time was significant (perhaps an extra twenty hours across the first launch), but the cost since then has been negligible. New features get localised at the time they are written, which is much faster than retrofitting localisation later.
The general lesson is that decisions about scope tend to be easier to defend if they are made at the start than retrofitted later. Localisation, accessibility, dark mode support, all three platforms (iPhone, iPad, Mac), these are easier to build in than to add later. The temptation when starting is to skip them in favour of getting to market faster. The cost of that decision compounds with every later feature you have to retrofit.
The first submission rejection
The first time I submitted to the App Store, the review failed. The reason was procedural rather than substantive, Apple wanted clarification on something in the description and screenshots, not a problem with the app itself, but the failure mode was the same. The submission sat in Apple's queue for several days. The "In Review" status that I had been watching daily became "Rejected". The email I received was politely worded and made the path forward clear, but the experience felt larger than it should have.
This is one of those small developer experiences that no amount of reading about it prepares you for. Indie developers describe the first rejection as a rite of passage and they are not wrong. The fix took two hours. The emotional reset took longer.
The second submission was approved. The third, fourth, fifth, and many subsequent submissions have mostly been approved on the first try, with occasional procedural questions that resolve quickly. The lesson is that the App Store review process is fundamentally cooperative rather than adversarial, but it takes a few cycles to internalise that. Apple has a job to do; their reviewers see thousands of apps; they are looking for specific things; meeting their criteria once teaches you what to do every subsequent time. The first rejection feels personal. By the fifth submission, the review process is just an unremarkable part of releasing software.
Getting the first hundred users
The first users came from posting in the PVOutput forum. The community there is the natural audience for a PVOutput app: small, dedicated, knowledgeable, and reachable in a single thread. The post got a few responses, the first paid users appeared within a week, and the small but real flywheel started turning.
The second wave came from posting in Dutch on Tweakers and on a Dutch solar enthusiast forum. Tweakers in particular has a culture that appreciates technical detail and a low tolerance for marketing spin, so the discussion was demanding but constructive. Users found bugs that I had not found. Users suggested features that were genuinely better than what I would have built unprompted. Users compared the app to its competitors with the kind of detail you cannot get from a survey.
The third wave came from Reddit (r/solar, r/iOS, r/homeassistant when a feature became relevant), from MacStories (a pitch to viticci@macstories.net for review consideration, which did not produce coverage but felt like the right step), and from word of mouth in the Belgian PV community. Each channel produced a small number of users; collectively they added up to something.
The lesson on distribution is that for a small niche app there is no single magic channel. There are several adequate channels, each producing a handful to a few dozen users, and the work is to find them, post in them appropriately (which means not as a marketer, but as a fellow user of the thing), and treat the responses with respect. Indie distribution in 2026 is closer to the early-2010s blogosphere than to the App Store's recommendation algorithm. It is slow and personal, and it works if you give it time.
The pricing question
The original price was €2.99 for the Plus tier unlock. After a few weeks of live use and a major version revision, I raised the price to €6.99. Existing buyers kept their unlock at the old price; only new purchases paid the new amount. The pricing argument was straightforward: the app had grown significantly since launch, the value proposition was higher, and €6.99 was still well below what equivalent professional tools cost. The pricing concern was real: would a price increase deter the user base?
Empirically, the answer was no. Conversion rates after the price increase were comparable to before. The buyers who valued the app paid the new price without complaint; the buyers who would have churned at the old price were probably going to churn anyway. The lesson, which I had read in other indie developer accounts but did not fully internalise until I saw it in my own data, is that most indie apps are underpriced relative to the value they deliver. The price is rarely what loses you a sale. The fit of the app for the user's actual need is what matters.
The current pricing, €6.99 one-time, with a free tier that covers one real system, is intended to stay stable for the foreseeable future. A subscription Pro tier might be added eventually for features that require ongoing service (cloud forecasting, multi-system aggregation), but the core app is a one-time purchase, and that is the model I expect it to keep.
What I would do differently
Looking back at those months of work, the things I would do differently are mostly small and obvious in hindsight.
I would start the analytics from day one, not from a later version. The early weeks produced data that would have been valuable to keep, and I missed it because I had not yet figured out how to collect it without violating my own privacy principles. (I eventually did figure it out; see The privacy question: what data does a solar monitoring app actually need?.) That lost data is gone.
I would write more tests. The investment in unit tests felt slow at the time but the dividend has been significant: refactoring an app that is well-tested feels qualitatively different from refactoring one that is not. The places in the codebase where I cut corners on testing early on are the places where I am still nervous to make changes.
I would document architectural decisions as I made them. Several times during this project I have had to reverse-engineer my own design choices because I could not remember why I had made them. A short architectural note at the time would have saved hours later.
A note on working with AI assistance
I mentioned earlier that I used an AI coding assistant throughout this project. I want to say a bit more about that here, because the topic is loaded and I think the loaded conversations miss the actual texture of how it works in practice.
The model that worked for me was treating the AI as a senior collaborator with deep knowledge of the platform but no knowledge of the specific project context, and no investment in the long-term outcome. Every piece of code it generated, I read. Every architectural suggestion, I evaluated against my own instincts and the documentation. Every "this is the standard pattern for X" claim, I verified before adopting. When the AI made mistakes, and it made many, I caught them because I was reading carefully, not because the AI told me. The responsibility for the code in the app is entirely mine. The leverage was real but it required engaged use, not delegation.
The honest assessment is that without this tool, this app would not exist. The version of me with a strong IT background but no native iOS experience would have hit the wall of Swift idiom and SwiftUI patterns long before the app was finished, and either given up or shipped something significantly worse. The version with the tool was able to ship something I am proud of. That is the actual story of how a lot of indie software is being built in 2026. The developers who say they are not using these tools are sometimes telling the truth and sometimes hiding embarrassment; the conversation deserves to be more honest than it usually is.
Where it goes from here
The roadmap from here is, in order: a few small fixes and improvements for the existing core features, then deeper analytics and forecasting (likely the Pro tier when the time comes), then an Apple Watch app in a major version that will sit alongside the current iPhone/iPad/Mac product. None of these is urgent. The app does what it set out to do, and the question of what to add next is being driven by which features users actually want rather than by what would be technically interesting to build.
The longer-term question is whether HelioPeak grows into something that requires more than one person's spare time, or whether it stays in the indie-craft territory it currently occupies. I do not have a strong opinion yet. Both paths are viable for an app in this niche. The thing I want to avoid is the path where ambition outruns capacity and the quality suffers.
A closing thought, for the series
This has been the fifteenth and last article in the series. Across the previous fourteen, I tried to share what I have learned from years of running residential PV in Belgium, monitoring it with PVOutput, and thinking carefully about what the data is and is not telling me. The goal was to be useful to other owners going through the same learning curve, not to sell anything in particular.
If you have read this far, you have my genuine appreciation. Solar in Belgium in 2026 is a more interesting problem than it gets credit for, and the people who care about it tend to be the same people who care about doing the small things well. The data on your roof, the choices you make about how to use it, the apps you trust to show it to you, the conversations you have with your installer when something looks wrong, all of these compound over the 25 years your panels are up there.
HelioPeak is, in the end, just one tool in that landscape. If it is useful to you, that is the highest compliment. If something else fits your needs better, please use that. The point was never the app. The point was the data, and the relationship to the data, and the long view.
Thanks for reading.