JoeSing
Personal karaoke through Spotify: it follows the track you are listening to and shows the lyrics synced word by word, designed for the living-room TV.
The problem
Karaoke at home is done badly: videos with poor audio and ads, or backing tracks to buy. Anyone with Spotify Premium already has the catalogue; the only missing piece was the lyrics, synced and readable from three metres away.
In 2026 Spotify limits independent apps to five accounts and no longer lets you check Premium from the profile. The constraint became the design: each user registers their own Spotify app and pastes its Client ID, so the quota is theirs and Premium is verified by the connection itself.
How it works
Structure
The browser never talks to Spotify: a PHP worker polls Spotify once per account and keeps the state in the database, and every screen reads from there. Only accounts with an open screen are polled, more often near the end of a track.
Usage flow
A four-step wizard walks you through creating the Spotify app, with the redirect address copied at the press of a button. Then you just press play on Spotify: JoeSing recognises the track, loads the lyrics and shows them full screen, with customisable styles.
Technical choices
OAuth with PKCE, never asking for the Client Secret; tokens encrypted with AES-256-GCM. The position in the track is recomputed on every frame from the server's latest sample, so errors do not add up. Lyrics come from LRCLIB: synced when available, plain as a fallback.
Known limits
It needs Spotify Premium and some confidence in creating an app on the developer portal. The Pro plan is paid by bank transfer and confirmed by hand: there is no card payment.
Numbers
| Lines of PHP, approx. | 18,000 |
|---|---|
| Lines of JavaScript, approx. | 7,400 |
| Dedicated tables | 22 |
| Module classes | 23 |
| Automated checks, approx. | 450 |
Stack
- PHP 8
- MariaDB
- JoeCMS
- JavaScript
- Spotify Web API
- LRCLIB
- systemd