Today's update is not about a shiny new button. It is about making Fibich easier to build on.

Recently I picked the project back up and started by dealing with some technical weight that had accumulated. The biggest change is that the audio engine dependencies are no longer embedded directly in the project as bundled frameworks. Fibich now uses the SFBAudioEngine package through Swift Package Manager.

That sounds like housekeeping, but it matters a lot.

A hi-fi audio player depends heavily on its playback layer. Support for formats like FLAC and other lossless or less common audio files should not rely on a pile of manually stored binary frameworks inside the app repository. That approach works for a prototype, but it becomes awkward over time: the project gets heavier, updates are harder, and the build setup becomes easier to break.

Package management makes dependency updates repeatable and removes bundled binary frameworks from the repository. It also makes future audio-engine updates easier to track.

The other big piece today is a refactor around library loading.

Fibich needs to scan folders, read audio files, generate library items, and persist the result. Earlier versions had too much of that logic gathered in one central place. That made the code harder to reason about, especially because library generation is not instant. It touches the file system, reads metadata, and may need to process a lot of tracks.

So today I separated those responsibilities. There is now a dedicated path for generating the library, fetching stored items, and coordinating persistence. Some of the work has also moved toward Swift's async/await model, which is a better fit for operations that take time.

The interface should remain responsive while Fibich scans the library.

Scanning a music library is very different from updating a label on screen. The app needs to do real work, but the interface should remain calm and responsive. This becomes especially important for larger local music collections, where hundreds or thousands of audio files may be involved.

There is also a new intermediate model for library items while they are being created. That helps keep unfinished file-scanning data separate from the stable items the app eventually stores and displays. It is a small architectural detail, but it solves a real problem: not every piece of data is ready at the same time, and the app should not pretend it is.

Fibich now has separate components for playback, library generation, persistence, player state, and the interface.

There is still plenty to do. The library needs better browsing, sorting, and filtering. Playlists need to become more capable. Metadata still deserves much deeper tools. Today's work makes those changes easier to build.

A good music player should feel simple on the surface.

Underneath, Fibich now has a cleaner engine room.