← Ecosystem

JoeSing

sing.giorgiopalermo.com in production

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
Screenshot of JoeSing