All work
case study · P/03Built on open source

Music streaming app

A music app where friends can see what each other are playing in real time and message about it. It streams uploaded songs from S3 and a catalogue pulled from YouTube and Jamendo.

Role
Extended an open-source base
Timeline
Nov 2026 · 8 of 11 commits
Platforms
Web · iOS · Android
Links
Live ↗GitHub ↗

Straight talkStarted from an open-source realtime Spotify-clone tutorial. My work: the entire React Native app, moving storage from Cloudinary to S3 and auth from Clerk to JWT, three external catalogues, the catalogue cache, and the production deployment.

What I built, layer by layer.

backend
Express + Socket.IO API
  • Real-time presence, activity broadcast and DMs stored in MongoDB
  • Songs and albums in S3, served through 1-hour presigned URLs
  • YouTube and Jamendo catalogues with a stale-on-error disk cache
Express 4 · Socket.IO 4 · Mongoose 8 · AWS SDK v3 · node-cron
mobile
React Native player
  • One player interface driving either TrackPlayer or a YouTube WebView
  • Home, Search, Album, Library, Now Playing, Chat and a mini-player
  • Background playback with lock-screen controls
React Native 0.88 · react-native-track-player · Zustand
infra
Self-hosted deployment
  • App, admin and API on separate subdomains behind Caddy auto-HTTPS
  • Mongo cache capped at 0.25 GB to fit a 1 GB server
  • One-command rsync + docker compose deploy script
Docker · Caddy 2 · MongoDB 7 · AWS Lightsail

Engineering decisions.

  1. 01Cache the catalogue for a dayEach YouTube category costs ~101 of 10,000 free daily quota units. A 24-hour on-disk cache that serves stale data on provider failure keeps the app inside the free tier.
  2. 02One player, two enginesA single interface switches between native TrackPlayer and a YouTube WebView, giving full-length playback without breaking YouTube's terms — at the cost of two playback paths.
  3. 03In-memory presence on one boxPresence lives in a Map in one container: simple and instant. Scaling past one instance would need a Redis adapter, a known next step.

By the numbers.

counted from the repository
23REST endpoints
10mobile screens
3live subdomains
24 hcatalogue cache
next project · P/04Shopvra →