Goodbye, Apple Music: Vibing a player for an audience of one

AmperfyNative

There is a category of software that barely exists: software for one. Built by a single person, for a single user - themselves. In other words, me, moi-même. The economics rarely justify it, which is why so many good ideas sit on back burners for years, waiting for the tools to catch up with the will. The will is strong with me, and throughout my life, was nicht passt, wird passend gemacht (what doesn't fit, gets made to fit) is the philosophy I have worked with.

For years I wanted to replace Apple Music. My library sits around 12,000 songs today (I know, rookie numbers) and is heading toward 20,000–50,000; the service was never going to hold that gracefully. These are MP3s ripped (legally, right - cough) over the years (since 1997). The migration off Apple Music will be a post of its own, but I migrated to a self-hosted Navidrome instance running in Docker on my Synology NAS.

The client side... ehhhh. I considered many before I consolidated behind Amperfy. The original Amperfy app, built iOS-first and ported to the Mac, never felt like a true desktop player. It struggled at library scale, buried the metadata-dense, spreadsheet-style browsing I had relied on in iTunes for years, and treated the Mac as an afterthought. I worked around it for a day, or two. Then I stopped.

I would build my own... forget the Blackjack. And so AmperfyNative was born - a native macOS client for Navidrome and Subsonic-compatible servers, hyper-customized to exactly how I listen and organize (ol' ADHD me).

There was one problem: I lacked the depth of knowledge. SwiftUI, AVAudioEngine, SQLite FTS5, buffer streaming, gapless transitions — none of it was territory I had real depth in. This is where agentic AI changed the math. With Cursor's Composer 2 as the harness, Hermes leading the orchestration, the project stopped being "someday" and became "this weekend." Starting from a spec document, I waxed poetic with Hermes for hours cogitating the ideal architecture, platform, and model to use. With $2 worth of tokens in the API used for orchestration (a mix of DeepSeek and GLM), and a $10 Cursor Pro plan, the project was born.

And now AmperfyNative exists: pure SwiftUI + AVAudioEngine, no Electron, no Catalyst, no web views, one third-party dependency. A three-pane layout with a sortable table exposing eleven-plus columns — title, artist, album, genre, rating, play count, date added, last played, favorites — plus the enable/disable checkbox that skips tracks during auto-play without hiding them. Something I always wanted.

The engine is the heart of it. Buffer-streaming in 10-second chunks with three buffers ahead, true gapless transitions, configurable crossfade, a 10-band parametric EQ with ten presets, ReplayGain normalization, and 80%-completion scrobbling that updates locally and on the server. Media keys, Now Playing, Control Center. Lightning-fast full-text search over SQLite FTS5 that stays instant across 40,000 songs.

The architecture is cache-first: the app opens instantly from a per-server SQLite database, the full UI populated before the network is touched; a two-tier cover-art cache with request deduplication; per-server isolation so nothing crosses between servers. Against the original app, the wins are concrete: no network-blocked launches, optimistic mutations that roll back on failure, jank-free sorting, prefetched artwork, sleep/wake recovery at the exact playback position.

Software for one. The economics still don't make sense. But the tools finally do, and that is what took this off the back burner.

Subscribe to Tim Sodhi muses

Subscribe, or don't. Either way I won't spam you.
[email protected]
Subscribe