Formerly Cider for macOS, codenamed project2-swiftui
Important
This project is no longer actively maintained nor functional. This serves as a technical endeavour showing how SwiftUI, Rust and TypeScript can work together in a native macOS App
In August 2022, I joined Cider Collective as a 15-year-old developer to reengineer their then Electron-based Apple Music client in SwiftUI. From 2022–2024, I rebuilt their Apple Music client from the ground up before the era of agentic coding. The goal was simple: to develop a faster and more efficient version of Cider that could run on lower-end devices using native technologies like SwiftUI and Rust. This version of Cider integrated many services and APIs such as Firebase for authentication and Sentry for analytics. It was a full-stack solution with work done on the backend not seen in this repository.
This version of Cider provided significant performance advantages: it used 60% less memory and had marginally lower CPU usage even during playback. I have always been an advocate for making software with native technologies where possible and avoiding solutions like Electron at all costs, so I was naturally very passionate about the project and consistently contributed to it.
A multi-process architecture was developed for this version of Cider to ensure playback is never interrupted even if the main UI/main thread is locked up, which could happen with SwiftUI components in earlier versions of macOS. The multi-process architecture separates processes into the following parts:
- Main UI/Binary - Cider.app
- Playback Agent - as seen in MKJSPlayback.swift, deals with playback in a separate WebKit process with JavaScript interop code in CiderWebModules
- Cider Elevation Helper - used as a sandbox escape for publishing Discord RPC updates about the user's playback status
Since the main binary has App Sandbox and Hardened Runtime enabled, it is unable to update the user's Discord playback status because historically Discord RPC's UNIX socket was located at $HOME/Library/Application Support/Discord/discord-ipc-0 and that is outside Cider's sandbox environment. Cider Elevation Helper exists as an XPC helper escaping the sandbox and uses discord-presence in Rust via an FFI built by swift-bridge. Honestly, I still do not know how Apple allowed this back then.
Playback is handled by MusicKitJS in a WKWebView. Actions are initiated from Swift via a JavaScript bridge (interop code) in CiderWebModules. Information about playback such as the queue and the currently playing media is reported back to the main UI. In early versions, the WKWebView was hosted in a completely separate process but was later removed due to reliability issues. The DevTools panel can be decoupled from the main UI using private API calls.
Due to the nature of the technologies used, the app uses far less memory than the Electron-based counterpart. However, because of the quirks in SwiftUI, an app built in Swift does not necessarily equal fast and efficient. A lot of time was spent optimising the code and making it launch as quickly as possible. Aggressive caching of user information and internal data using KeychainAccess helped massively in terms of startup times, but knowing when to invalidate the cached data is very important as well.
I developed an auto update system from scratch because I hated how complicated Sparkle was. It checks for updates by fetching a release manifest from a Firebase endpoint and notifies the user if an update is ready to be downloaded. The auto update system then downloads the update and spawns Cider Elevation Helper as a detached XPC service to replace the current application bundle with the new one from the temporary directory.
The whole process avoids having to ask for user permission making the update procedure simple and seamless, completely without user intervention.
Internal tools were created to facilitate the development of the project:
- swift-precompiler for embedding static content in Swift similar to include_str! in Rust
- coke(Close sourced) for patching and installing CocoaPods from Git repositories with a simple Command Line Interface(CLI)
Much of this repository consists of custom build toolchains like Taskfile.yml which contains all the build scripts required to build the project. I essentially replicated a monorepo code structure without knowing what a monorepo was.




















