Inspiration
There's a TikTok trend where a group chat passes a song around — one friend records the first line, sends it back to the chat, the next person records the line after that, and so on, until a voice memo thread turns into a full cover with everyone's voice stitched together. It's scrappy and a little chaotic, but every time we watched one it was obvious why people love making them: nobody sounds perfect alone, but hearing your line land next to everyone else's is genuinely delightful.
We wanted that feeling, but without needing a group chat full of friends willing to embarrass themselves on command. What if the "group chat" was just... the internet? Any stranger could add the next line to a song already in progress, the same spontaneous, anonymous-but-connected spirit as talking to a random person on Omegle, except instead of a conversation you're building something that outlives the session — a shared recording that keeps existing after everyone's logged off.
What it does
Fruit Salad turns singing into something you do with the internet instead of alone in your room. A song is broken into short lines — we call each one a Fruit. You open the app, browse the song library on a scrollable shelf (with real cover art pulled live from Apple's iTunes Search API), pick a song, and claim one or more open lines to sing.
When you hit record, the backing track plays through your headphones with a count-in timed to your exact line, your mic is captured on the same audio clock as playback, and you can review and re-take before submitting. Your take is uploaded and stored against that song's shared, permanent Rendition in our Supabase backend — so the next person to open that song sees which lines are already filled and picks up wherever the last stranger left off.
The whole UI — the sprouting fruit icons that bloom in the background as lines get filled, the shelf of songs, the salad/gallery navigation — is our own hand-drawn art, not a template.
How we built it
The hard, non-negotiable constraint for this project was timing: if a chorus of strangers' voices doesn't land on the beat, the whole idea falls apart. So the core of Fruit Salad is a custom Web Audio engine, not <audio> tags:
- Sample-accurate scheduling. Every clip — backing track and voice — is decoded into an
AudioBufferand scheduled withAudioBufferSourceNode.start(time)against a single sharedAudioContextclock, so nothing drifts the way multiple<audio>elements do. - Clock-anchored mic capture. Instead of
MediaRecorder, which runs on its own wall-clock timeline, we capture the mic directly onto the sameAudioContextclock used for playback. That lets us slice out the exact window of audio that corresponds to a given moment in the song, sample-accurately, and even correct for real-world speaker/headphone output latency so what you hear and what you sing stay aligned. - Shared reverb + loudness normalization. A synthetic convolution impulse response glues together mics from wildly different rooms, and we compute RMS-based gain per clip so twenty different recording setups sound like one intentional performance instead of twenty volumes fighting each other.
- Next.js + Tailwind, deployed on Vercel, for the frontend, with Supabase (Postgres + Storage) behind two API routes: one that finds-or-creates the shared public rendition for a song and returns every line's fill state, and one that accepts a finished take, uploads it to storage, and records it against its line.
- LRC-style timestamped lyrics drive per-line start/end times, which is what lets the count-in, recording window, and playback all agree on where a "line" actually begins and ends.
Use of Reve
Every fruit scattered across Fruit Salad's background — the apples, blueberries, lemons, oranges, and pears that tile the homepage and sprout one by one as lines get sung — started as a hand-drawn illustration. We fed those hand-drawn pieces into Reve to animate them, generating a second redrawn frame for each fruit that we swap between in CSS to get a loose, stop-motion "boil" wobble instead of a stiff, static icon.
Challenges we ran into
Sync was the challenge we designed the entire project around, and it still took real iteration: our first pass used MediaRecorder, which has unpredictable startup latency and drifts against the Web Audio clock. Rebuilding mic capture on the AudioContext clock itself — and later accounting for device output latency, since a singer reacts to what they hear, not to when we schedule the audio — was the difference between "technically works" and "actually sounds together."
We also ran head-first into the same wall every music hackathon project hits: licensing. Building around real commercial tracks for the demo meant navigating what we could legally use for testing versus what a real launch would need (karaoke catalogs or commissioned originals).
Accomplishments that we're proud of
Every visual element in Fruit Salad — the fruit sprites, the icon set, the overall layout — was hand-drawn and hand-designed by our team, not pulled from a UI kit. Getting that to sit on top of a genuinely hard audio engineering problem, and having both come together into something that feels cohesive rather than like two separate projects bolted together, is what we're most proud of.
What we learned
We came out of this with real hands-on experience in low-level Web Audio timing — buffer scheduling, clock-anchored capture, and the subtlety of output latency compensation — plus practical experience wiring a resumable, multi-user backend on Supabase where the state of "who's filled what" has to stay consistent as different strangers drop in and out.
Underneath all of it, the thing that stuck with us is the same thing that inspired the project: a shared song, built line by line by people who'll never meet, is a small but real piece of connection. Every fruit that sprouts on screen is someone's voice, and that's worth building carefully for.
What's next for Fruit Salad
- Live claims and real-time presence — a soft-lock system (60-second claim window) on Supabase Realtime so two strangers can't record the same line at once, and lines light up live as they're filled.
- A public gallery of sealed renditions — once every line of a song is filled, seal it, publish it permanently, and start a new pass. The gallery page exists today but is an empty placeholder until this is wired up.
- Growing album art via Reve — hand-crafted cover art that visibly gains characters as more strangers contribute to a song, so the artwork tells the same "growing crowd" story as the audio.
- Pitch smoothing — gentle automated pitch correction and time-warping to blend takes recorded slightly off-key or off-tempo into something that sounds more like one performance.
- A bigger, licensed song library, and a one-click video export that stitches the finished mix, growing cover art, and synced lyrics into something shareable.
Built With
- next.js
- postgresql
- react
- supabase
- tailwindcss
- typescript
- vercel
- web-audio-api


Log in or sign up for Devpost to join the conversation.