Building a player around ownership
Sidus is a native music player for people who already own their library and want it to remain useful without a subscription, a streaming catalogue or another account.
The project began in September 2025 as an iPhone player for local and iCloud files. It grew into a product system spanning iPhone and Mac, with a shared playback core, portable playlists, karaoke, CarPlay and optional AI features.
I owned the product direction, interaction design, visual system and implementation. Working on the product end to end made technical constraints part of the design process: file access, background playback, metadata quality and recovery states shaped the interface as much as the screens did.
The current product is a working native application rather than a speculative prototype. This case focuses on the decisions that turned a capable file player into a coherent daily listening product.
Where the project started
The first version solved a narrow problem: select music from Files and play it reliably on iPhone. It supported local storage and iCloud Drive, read embedded metadata and kept playback alive in the background.
That technical foundation worked, but it still behaved like a utility. People with a real music collection do not think in file URLs. They think in tracks, albums, artists, playlists and the song that should continue when they leave the app.
The product question became larger: how could a listener keep the ownership and resilience of local files without giving up the organization and polish expected from a modern streaming product?
The problem was not access to music
A local player can open a file. A daily music product has to preserve a collection through interrupted downloads, moved folders, imperfect tags, device changes and hours of background playback.
Core product insightOwnership only feels valuable when the library remains understandable and dependable.
Four recurring pains shaped the work. Music was scattered across local folders and cloud providers. Metadata could be incomplete or inconsistent. A lost permission could make a collection appear to disappear. And useful online features often came bundled with an account, tracking or a hosted catalogue.
Sidus needed to remove those compromises without pretending that local files are simple. The interface had to explain where music came from, what was available offline and how to recover access without ever risking the originals.
Research through building and daily use
Sidus did not begin with a formal research study. The evidence came from shipping a narrow player, using it as a real library and tracing the moments where the product stopped feeling dependable.
Early builds exposed the sequence of problems. Opening a file was easy; keeping access after it moved was not. Background audio worked until an interruption or route change. A screen could look correct while the queue, Lock Screen and CarPlay disagreed about what was playing. Each failure revealed a product requirement that a static concept would have missed.
- 01Reliable file playback
The first iPhone build proved that owned music could remain useful without a hosted catalogue.
- 02A library, not a picker
Local files and iCloud became persistent sources with indexing, metadata and recovery states.
- 03One session across contexts
Background audio, Siri, system controls and CarPlay turned playback into a product-wide state.
- 04Native continuity on Mac
A shared core carried meaning and data across devices while each client kept its own interaction model.
This changed the role of design. Instead of decorating a finished architecture, the interface made technical truth visible: whether a source was available, whether a track was local, which action would change data and how the listener could recover.
Product principles before features
The product became easier to scope once ownership was expressed as behavior rather than a slogan.
Playback starts from a file the user has explicitly made available. The database is a rebuildable index, not the source of truth. Disconnecting a source removes its catalogue entries but never deletes the original music. Network metadata, lyrics and AI remain optional.
Core listening must continue without Sidus servers, a streaming subscription or an internet connection.
These rules also created a boundary for new ideas. A feature could enrich the library, help organize it or make playback more useful. It could not turn a user-owned collection into a dependency on Sidus.
Designing the source model
The central object is not an account. It is a source: a local folder, iCloud Drive, another File Provider, an external disk or a network volume that the listener chooses through the system picker.
Sidus scans sources recursively, builds a local index and keeps the readable files as the authority. On Mac, multiple folders can stay connected at once. On iPhone, individual files and folders can coexist in the same library.
The difficult states became visible product states: scanning, partially available, downloading, permission lost, provider unavailable and reconnected. A stale source offers “Choose again” while keeping its last known library rows, so a temporary outage does not look like data loss.
One product, native on each screen
I separated product parity from layout parity. iPhone and Mac share the same concepts, playback behavior and portable data, but each client follows the interaction model of its platform.
A shared Swift package owns filesystem discovery, supported formats and platform-neutral rules. Native clients own permissions, lifecycle, system media controls and presentation. This keeps the core consistent without forcing a desktop sidebar into a phone or reducing Mac to an enlarged mobile interface.
The result is a single product model with platform-specific surfaces: compact navigation and full-screen playback on iPhone; searchable multi-pane browsing, drag and drop and a menu-bar player on Mac.
Turning files into a library
Once a source is connected, the interface stops asking the listener to manage paths. Embedded tags become tracks, albums, artists and genres. Search works across the whole library, while folders remain available when location still matters.
Home is designed for continuation: the current queue, recent music, favourites, newly added tracks and pinned collections. Library is designed for inspection. Collections give playlists and user-created folders their own space.
Local metadata remains intact. Corrections are stored as non-destructive overrides, so fixing a title or artwork does not rewrite the original file. Portable playlist manifests preserve organization and can relink missing tracks safely when sources change.
Playback had to survive the interface
The player is a persistent system rather than one screen. A compact Now Playing surface follows the listener through the app. The full player adds scrubbing, output routing, shuffle, repeat, queue editing, sleep timer, equalizer and track details.
Playback state survives relaunch: current track, position, queue and modes are restored. The same session continues through Lock Screen, Control Center, headphones, Siri, media keys and CarPlay.
This exposed a useful design test. If an action changed the song but not the underlying queue, every surface had to agree immediately. Visual consistency mattered, but state consistency was the real experience.
Karaoke as a listening mode
Lyrics began as supporting information and became a focused listening experience. Karaoke keeps the active line centred, exposes text size and language controls, and separates recognition language from translation language.
When synchronized lyrics are missing, the listener can explicitly generate them from an authorized local file. Work runs in a queue so playback and navigation continue. Generated results are cleared when the track changes and cached only when the request still belongs to the active song.
Translation is on-device by default where the platform supports it. A network model is a consented fallback, not a hidden dependency. This kept a sophisticated feature aligned with the same local-first boundary as playback.
AI that works for the library
Player AI and Playlist AI were added after the local product model was stable. Their job is to help a listener understand and organize an existing collection, not to become a new home screen or a prerequisite for playback.
Player AI receives bounded context about the current track, queue and library. Playlist AI turns a request into a typed plan, matches local tracks first and shows a preview before changing data. Destructive operations require confirmation and reversible changes offer undo.
Connections live in one profile surface and explain whether a capability is local, uses an external provider or creates billable cloud usage. The interface makes the privacy and offline impact visible before connection.
Designing for daily-driver quality
Most of the product work happened outside ideal screenshots. Bluetooth interruptions, background execution, stale permissions, low storage, duplicate imports and unavailable cloud files all had to resolve without damaging the library or stopping the next session.
Every major surface was treated as a state system: first run, loading, partial data, empty, offline, permission lost, provider unavailable, error and completed. Automated builds and UI tests protected navigation and playback contracts while device testing exposed the platform behaviours a simulator could not reproduce.
The design system grew from those repeated states. Shared headers, sheets, controls and feedback patterns reduced visual drift, but components were kept subordinate to the task. Queue editing, karaoke settings and provider connections share rules without pretending to be the same screen.
A user-owned library can feel modern without making an account or streaming catalogue the product spine.
Source health and recovery states create more trust than hiding file-system complexity.
Cross-platform consistency could not mean identical layouts. The product needed shared behavior with native surfaces.
AI can improve organization and listening, but only while it stays optional, bounded and downstream of the library.
What the project produced
Sidus became a working offline-first music product for iPhone and Mac, available through the App Store and supported by a live product site.
The shipped foundation includes local and cloud-folder sources, a persistent indexed library, broad lossless format support, playlists and folders, background playback, system integrations, CarPlay, equalizer controls, karaoke and optional AI assistance.
The strongest result is the boundary that survived that growth. New capabilities can be connected or removed, while the listener can still open Sidus, find owned music and play it without an app account or a Sidus-operated media server.
What comes next
The next product cycle is less about adding destinations and more about strengthening continuity. Download recovery, source health, index migration and conflict-safe synchronization need to feel as considered as playback.
Android is planned around the same portable product model, not as a visual copy of iOS. Future cloud providers will remain user-chosen transport and storage. Online discovery and concert data will appear only when backed by real authorized sources.
The goal is to let the product expand without weakening its original promise: the music, organization and listening history continue to belong to the listener.
What I learned
Local-first is an interaction model, not a storage setting. It changes onboarding, empty states, error recovery, architecture and the order in which permissions are requested.
A music player feels trustworthy when it preserves continuity. The current song, queue, source availability and user edits matter more than the number of discovery features on the home screen.
AI is most useful when it is downstream of a strong product model. Bounded context, preview and consent made it an extension of the library rather than a competing interface.
The project also reinforced a practical rule for cross-platform design: share meaning and behavior, then let each device express them in its own way.
