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
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.
- 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.
- 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.
- 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 repository23REST endpoints
10mobile screens
3live subdomains
24 hcatalogue cache