Skip to content

Philosophy: unopinionated

SwiftSonic is deliberately narrow. It does one thing — speak the Subsonic and OpenSubsonic protocols — and refuses to grow features that belong in the layer above.

  • No caching. Responses are returned as-is. If you want disk persistence, an in-memory LRU, or stale-while-revalidate, build it on top.
  • No audio playback. Streaming URLs come back fully formed; pair them with AVFoundation, AVPlayer, or whatever player suits your app.
  • No UI. No SwiftUI views, no UIKit controllers, no design system.
  • No business logic. Library queues, recently-played tracking, smart playlists — all out of scope.
  • No server-specific extensions. If a feature only exists on Navidrome (or Airsonic, or Gonic), it does not get a wrapper. Use the spec.

The audience is developers building Swift apps. Those apps already have opinions about caching, playback, persistence, and UI. A library that bundles its own answers forces friction on every consumer that wants to do things differently.

Keeping SwiftSonic to the protocol layer means:

  • One small, auditable surface to read.
  • Zero conflict with whatever architecture you’ve already chosen.
  • No transitive dependencies (no Combine, no swift-nio, no SwiftUI tag-along).
  • Spec compliance is the only contract — no “but this works on my server” exceptions.

PRs that extend the protocol surface (new endpoints, OpenSubsonic features that shipped in the spec) are welcome.

PRs that add caching, playback, or server-specific quirks are not. See Contributing for the full rules.