March 21, 2026

The road to Rigelian 4.0

How Rigelian 4.0 is rebuilt from the ground up.

Rebuilding Rigelian

In June of 2025 I decided it was time to start over with Rigelian.

The existing implementation had served me well for years, but it was starting to show its age. Over time a number of structural issues had accumulated, and fixing them incrementally no longer felt like the right approach. Instead, I wanted to rebuild the app with a modern architecture and a cleaner foundation for the future.

Why start from scratch?

Several things were holding back further development.

The project relied on quite a few external dependencies. While those packages were useful, they also slowed down builds and occasionally caused compatibility issues. Over time this made development more fragile than I liked.

The macOS version was another pain point. It was built using Catalyst, which worked reasonably well but never quite felt like a native Mac application. Certain limitations and UI quirks made it clear that a more platform-native approach would be preferable.

Localization was also something that had never been properly designed into the app. Adding multi-language support after the fact would have been a large task.

At the same time, the Apple ecosystem had evolved. Swift had gained powerful concurrency features, and SwiftUI had matured significantly. If I was going to rebuild Rigelian, this felt like the right moment to embrace those changes.

Modernizing the architecture

One of the most important architectural decisions was to move away from RxSwift and adopt Swift’s native async/await model.

RxSwift had been a great tool for many years, but async/await makes asynchronous code much easier to read and reason about. Moving to this model also aligned the project with the direction Swift itself is taking, which was important with Swift 6 on the horizon.

Another major change was adopting SwiftUI across the entire app. I had already moved several other projects to SwiftUI, and the benefits were clear: a single declarative UI framework that works across macOS, iOS, and iPadOS. This would allow Rigelian to share most of its UI code across platforms while staying aligned with Apple’s long-term strategy.

Rebuilding the core

Rigelian communicates with different player types, primarily MPD and OpenHome. Each of these is implemented in a separate connector package that conforms to a shared protocol used by the app.

Migrating this protocol from RxSwift to async/await became the backbone of the rewrite. The MPD connector was the first to be migrated, and the rest followed step by step.

The app itself was rebuilt alongside these connectors using SwiftUI. Rather than trying to port the old app feature by feature, I implemented functionality incrementally. Each new UI feature was developed together with the corresponding backend implementation in the connector layer.

Starting with macOS

Another deliberate choice was to start with a macOS version.

Only around 10% of Rigelian users run the macOS version, which made it a good platform for the initial releases. Launching there first meant that any issues in the new architecture would affect a smaller group of users while the app matured.

Once the architecture stabilizes, expanding to iOS and iPadOS becomes much easier.

Keeping dependencies small

One goal of the rewrite was to minimize external dependencies.

In the end only a few remain: Kingfisher for image caching — which is essential for efficiently displaying album artwork — and Firebase for crash logging and analytics. Apart from that, the only other dependencies are my own connector libraries.

Reducing dependencies not only simplifies builds, but also makes the project easier to maintain over the long term.

The routing model

Designing the navigation model turned out to be one of the most important architectural pieces.

The app uses a custom NavigationRouter that supports both two- and three-column layouts. It can control the root view of the second and third columns, and manage the navigation stack in the third column.

For this approach I took inspiration from the excellent NavigationPath routing tutorial by Natascha Fadeeva.

Rethinking the subscription model

The rewrite also provided an opportunity to rethink the app’s subscription model.

Previously, the free version of Rigelian limited access to certain features. While this approach worked, it also meant that users could not fully experience the capabilities of the app before deciding whether to subscribe.

In the new version, all functionality is available to every user. Instead of restricting features, the free version limits the number of times per month that music can be added to the play queue.

This approach allows users to explore the app more freely and discover its features without running into locked functionality. The hope is that this improves the onboarding experience and ultimately leads to better adoption of the subscription.

Localization from the start

Unlike the previous version, localization was built in from the very beginning.

The app was developed simultaneously in Dutch and English to ensure that every visible string was properly localized.

Towards the end of development I used the OpenAI API to translate the entire set of strings into ten additional languages. As a quick sanity check, I translated a few of them back into English to verify that the meaning was preserved. That gave me enough confidence to ship with these additional languages included.

CI/CD with Xcode Cloud

As development progressed I invited a small group of beta testers to try the new version. Their feedback was extremely valuable in identifying issues and polishing the user experience.

To streamline the release process I adopted Xcode Cloud for building and distributing the app through TestFlight.

I was pleasantly surprised by how easy it was to set up. Keeping the dependency tree small likely helped here as well. The 25 hours of compute time included with the €99 Apple Developer membership are more than sufficient for an independent developer.

Renewing the website

Finally, in the spirit of a fresh start, the website for Rigelian was also rebuilt.

The old site was based on WordPress, which had served its purpose for many years but had gradually become harder to maintain and slower to load. The new website is built with a much simpler and faster setup, making it easier to maintain and improving the overall performance and appearance.

This transition is described in more detail in a separate blog post: Bye Bye WordPress.

Looking ahead

Rebuilding Rigelian from scratch required a significant investment of time, but it resulted in a much cleaner and more modern codebase.

With SwiftUI, async/await, a simplified dependency tree, and proper localization support, the app is now much easier to maintain and extend. Starting with macOS allowed the architecture to mature before expanding to other platforms.

With this new foundation in place, future development of Rigelian should move faster and remain better aligned with the direction of the Apple ecosystem.