Part 1 — I Just Wanted a Better Music Player

There is a very specific kind of frustration that slowly builds over years of using software that almost does what you want.

Not catastrophic frustration.
Not rage.
Just a thousand tiny compromises.

Music apps that:

  • treat your carefully curated library like disposable streaming content

  • lose metadata

  • struggle with large local collections

  • feel sluggish with FLAC libraries

  • hide your files behind proprietary abstractions

  • or simply refuse to respect the idea that your music collection is something personal.

That frustration eventually turned into Needle.

At the beginning, the idea was almost modest:

Build a proper local-first desktop music player.

Nothing cloud-based.
Nothing social.
Nothing algorithmic.

Just:

  • fast local playback

  • beautiful library management

  • proper metadata handling

  • support for lossless audio

  • and software that respects ownership.

The stack itself was fairly modern:

  • Tauri

  • React

  • TypeScript

  • Rust

  • mpv for playback

The goal was not to reinvent Spotify.
The goal was to reclaim the experience of owning a music library.

And honestly?
That part alone would have been enough.

But personal projects have a dangerous tendency:

Once they become genuinely useful to you, your standards rise dramatically.

You stop thinking like:

“Can this technically work?”

And start thinking:

“What would make this feel truly right?”

That question changes everything.

Because eventually one very specific thought appeared:

What if playback state synced across devices?

That was the moment the project quietly crossed an invisible line.

Because synchronized playback does not belong purely to a desktop app anymore.

It requires:

  • shared state

  • identity

  • persistence

  • session management

  • communication between devices

In other words:

A backend.

And just like that, the simple local-first desktop player suddenly became the foundation for something much larger.

The funny thing is that none of this was planned.

There was never a grand architecture document.
No “roadmap toward platformization.”
No startup pitch deck.

Just:

“This missing capability annoys me enough that I should solve it properly.”

That single mindset turned out to be responsible for everything that came next.