SoundHive: A 10-Year Side Project

This project has had many names over the years. Always on my mind, but it never really gained traction to the point where it was an actual POC. It all started probably in 2014-2015.

My first job right out of college revolved around music socially - going to shows, hanging with friends and listening to music. In those mid 2010’s you had to share the device so that folks could add the songs they wanted to the queue. Known for hogging the music queue, I always ended up playing Babasonicos. That’s where the idea for a collaborative playlist came to my head. Back then my work was as a Java Engineer, working on a Java GUI that installed databases; my only knowledge of web UI’s or frameworks was OracleJet - now you probably know which DB the installer was for. The idea was simple: Spotify and the availability of data plans on cellphones made the possibility of a session where friends could collaborate in real time more tangible. Shared playlists had been possible, but the real time aspect was not there. Every road trip was just another testament of how the idea had some legs - everyone wanted to add their songs, but that phone had to pass through so many hands. Then came the usual “Oh, I think I replaced the entire queue, sorry peeps.” Just remembering made me chuckle. But in the end it stayed like that: an idea, a thought, nothing else.

Time passed and around 2017-2018 the Bay Area became home. Even with the “formal” training of a software engineer, all of these new frameworks were foreign to me. React was all the rage, and Redux for managing application state - oh and don’t get me started with those thunks. A whole new world. A programming bootcamp seemed like the right move; not to learn how to code (but it was helpful for getting interviews and prepping for them), but to learn more about new technologies and be surrounded by like minded people.

Back in the day meetups were a great place for community. They were mostly about recruiting, but the learning, the talks, and the people you met were amazing. That cool developer scene - Discord, Lyft, GitHub and their cool offices - got its hooks in me. Rails and React became my tools during 2017. Becoming an instructor at the bootcamp allowed me to still be in the Bay Area, get some money, and stay around friends made along the way.

In 2018 a Rails project to build the idea began. Gotta admit, a lot of time went into thinking about architecture - plan plan plan, no act. The whiteboard of the bootcamp offices was covered in component diagrams. The idea was to first come up with the queue and voting system.

Finally, development started with Rails and React. There was no infrastructure besides Postgres as the DB. Looking at my commits from that time - damn, it took only a few commits before giving up. The culprit: DB connections were not being released and the server kept crashing. This was also when my one and only Stack Overflow question was asked.

About 3 months in, the project was abandoned. The only update after that was fixing a vulnerable dependency.

And that’s how the project went on ice. The idea was always there and every social interaction reminded me that a collaborative playlist was a good idea. In bars you could set songs by paying for credits and then allowing patrons to use those credits to add songs to a queue. Playing good old 2010’s emo and hardcore songs at bars in Seattle was a blast :) but the idea didn’t continue for quite some time.

7 years passed with no updates or progress. What happened? Life. A job at Amazon came shortly after. The first years there were a struggle - working like crazy, feeling like an impostor. Even after becoming a Senior Engineer, the impostor feeling continued. After years of working on it, comfort finally came, but that’s 7+ years in the making. Code became work, not joy. Simply too tired to code for fun. Being promoted to Senior was also no walk in the park - it required some nasty grinding. Every day, 7 days a week, either working on projects or working on that promotion doc.

Mid 2025, tech content on YouTube started filling my feed as the popularity and capability of AI picked up. GenAI had become capable enough that learning a new language from scratch wasn’t necessary to build something - it lowered the barrier. Focus shifted to ideas and architecture while the AI handled the boilerplate. The starting point was a brain dump on t3.chat, a web application that lets you chat with most existing GenAI models. Whatever was the most capable model at the time could be selected - Gemini Pro 2.5 was good at coding, or Sonnet 4.5, now it’s Opus 4.5. The idea got refined into a prompt to let a coding agent give it a try. The application needed to be reactive - as users upvote songs, components should update themselves. Chef by Convex became the agent of choice, handling both frontend and backend with Convex as the reactive backend. At that time there was no control or visibility of the context size, so a PoC was possible but everything was in a single session. Context rot was definitely a thing, plus there was a time where the conversation was too long for the model to handle.

And so finally a working PoC: Votune. This try at it had all the base mechanics, leveraging the YouTube iframe player. A clunky (clearly generated by AI) UI with too many features.

The requirements were simple:

  1. An admin would be able to create a session that guest users could join to add songs.
  2. Guest users would sign in anonymously.
  3. Guest users would be able to search for songs (through YouTube) and add them to a queue.
  4. Guest users would be able to upvote and downvote songs.

As the agent worked, more and more features crept in. Since adding features became as easy as prompting for them, why not go to town with it:

  1. Admin dashboard - where configurations could be updated.
    1. Admins could kick users from the session.
    2. Admins could grant more votes to all users.
    3. Admins could reset votes for songs or remove songs from the queue.
    4. Admins could update cooldown settings (minutes before a song could be suggested again and seconds a user would need to wait before adding another song to the queue).

Convex made the UI reactive. Songs added by any user would appear on the queue, votes were also reactive, even the progress of the songs being played. Initially users could spend all of their votes on either upvotes or downvotes - gamification to express if they loved or hated a song. Once a song that a guest user voted on was played, votes returned to the user.

The ease of adding features was a double-edged sword. Instead of focusing on the overall user journey, I was unknowingly rotting the context, and every feature was slowly being done with less quality. But despite the clunky UI and feature bloat, it was time to test it.

One night with friends over, the Mac was mirrored to our Apple TV and the QR code was shown so folks could join. Friends started joining in, searching songs, adding them to the queue, and voting. It was a blast, and a few things became apparent from this night.

My friends have a good mix of software engineers and non-software engineers. Was not fully surprised when the engineers started gaming the system, but these exploits weren’t anticipated:

  1. They liked the gamification of the votes, but they found a way to abuse it. When a song was about to finish, they voted on another song multiple times so it jumped to the top. Since votes were returned to users after the song they voted on was played, they kept doing this again and again.
  2. Anonymous guest sessions were stored in the browser’s localStorage, so my friends started creating multiple sessions across their mobile browsers to cast even more votes.

Don’t trust users.

From that night a few changes came to mind. Most importantly, the overall idea worked - folks had fun. But the fun came to an end when the application started failing. Searches on YouTube began to fail. The YouTube Search API has a quota of 10,000 units per day, but each search consumes 100 units - so effectively only 100 searches per day. That limit was reached. Luckily the night was ending anyway.

A few adjustments were needed:

  1. The queue would freeze when a song was 75% completed, to avoid last minute voting abuse.
  2. Admins could disable downvotes.
  3. Admins could disable signups/joining a session. Why? The fear of someone simply joining or creating a bunch of sessions since this was publicly available. Once my friends were logged in, the ability to join was closed.
  4. Users could only cast 1 vote, either upvote or downvote. They could still remove their vote.
  5. Admins had a stats view to see which songs were played, the votes for each song, and who voted on it.

Sadly here is where the first real obstacle came. Investigating more about the YouTube API quota, the realization hit: even for a simple night with 5-6 friends, after 2 hours we would run out of calls to YouTube Search. You can request a higher quota, but that stage hadn’t been reached yet.

Alternatives were considered:

  1. Allow guests to copy links from YouTube and paste them to be added to the queue. But this meant retrieving song information to display it in the queue. Too much friction - a no go.
  2. Scrape songs from YouTube and keep my own inventory. Probably against YouTube’s TOS and fragile if URLs change.
  3. Use YouTube Music instead of YouTube Video search. This would also help guarantee what’s played is actually a song.

At this point the understanding was clear: while the idea had legs, YouTube Video search was simply not going to work. Revisiting this with Spotify or Apple Music as music providers was necessary. YouTube was the wrong provider anyway - you could add any video, not necessarily music. Good for initial feedback, but not the right fit.

Since the project was all done within the chat with Chef App, there’s no accurate tracking of engagement with the project. A few adjustments were made and pushed to git.

A few weeks later, the idea was picked up again. This time v0.app by Vercel was used to generate a new UI and simplify the overall user flow when voting:

  1. Once a vote is cast, that’s it - no updates.
  2. Still used Convex for reactivity.
  3. Removed the config dashboard and stats to focus on a simple user journey.

The feedback from that test night was taken into account. My friends suggested removing downvotes entirely - ideally songs that people don’t like simply won’t get upvoted, so it’s better to bubble up songs people like through highest upvotes rather than pushing them down with downvotes. Downvoting seemed to have a negative connotation that promoted abuse. Still unsure about this since it was part of the gamification, but the change was made.

Why not look for music provider alternatives? Honestly, a new coat of paint seemed like enough to keep playing with friends even if capped at 100 searches. This time it was called SoundHive.

As you can see from the chart, nothing happened in September, October, November, or December. Working, working, working. Not a lot of time, simply too tired, and no way forward with the YouTube API limitation in sight. Just didn’t have the energy, so SoundHive went on pause.

In December, a visit to my brother and family in my hometown in Mexico led to an interesting discovery. At a karaoke bar, you had to write your song requests on a piece of paper and the bartender would add them to an Apple Music playlist. They shared it on their TVs and sound system - the Apple Music player with the lyrics - and gave you microphones to sing along.

That got me thinking. My idea is not that bad, right? Plugging this into Apple Music could even make it sellable. A cheap license, maybe a few bucks - haven’t thought it through - but this could be done. That re-energized me.

Coming back in January 2026, the plan was to continue with the UI we had, fix whatever bugs were there, but this time update the code so we could easily switch music providers. An admin could create a queue for Apple Music or Spotify.

A few tools were tried. First up was Kiro IDE - about 500 free messages available, so those were used working with Opus 4.5 and just going at it. This time everything was local. Convex handled local deployments that would match what it would look like in prod, which was pretty sick. YouTube was still used for testing. Kiro CLI and OpenCode were also tried. Zen and Grok code too - they were free, but they just did not feel as capable as Opus 4.5. Stuck with Kiro and made a few commits over January.

After that, time to look at music providers. As an Apple Music premium subscriber with access to that cool karaoke feature, that seemed like the place to start. To my surprise, if you want access to queue and search APIs, you need to be in the Apple Developer Program. There’s a JS SDK called MusicKitJS where you can access the queue APIs, but you have to pay $99 a year. That threw me off. Not doing that yet.

Spotify looked like it could work, but would also need Spotify Premium. That held things off for a bit.

The YouTube Music API (if it exists) should probably be explored as a replacement before biting the bullet with the Apple Developer Program. The new UI hasn’t been tested with friends yet. The anonymous session abuse problem also hasn’t been solved - there’s a tension between making the guest flow frictionless and preventing people from creating multiple sessions. Maybe preset users per “table” that scan and get logged in? Need to mull that through.

For now, SoundHive is a weekend project. Working on it here and there, probably a few hours on weekends. The next step is solving the music provider problem and verifying if the new music-provider-agnostic architecture actually works. If another music provider gets working, there will be another test night with friends.