A LAN-hosted Spotify party queue app. The host authenticates with Spotify, guests scan a QR code and add songs to the queue — no accounts, no friction.
- Host opens the app, clicks New Session, enters a session name and their name
- Spotify OAuth flow runs — the host authorizes playback control
- The app shows a QR code guests can scan to join
- Guests search for songs and tap to add them to the queue
- Songs queue up on the host's active Spotify device
- Monorepo: Bun workspaces
- Server: Bun + Hono + tRPC
- Web: React 19 + Vite + TanStack Router + TanStack Query + TanStack Form
- UI: shadcn/ui (Radix + Tailwind CSS)
- Shared: Zod validators
- Bun v1.0+
- A Spotify Developer account with an app registered
- Go to the Spotify Developer Dashboard
- Create a new app
- Under Redirect URIs, add:
http://localhost:4000/auth/callback - Note your Client ID and Client Secret
cp .env.example .envFill in .env:
SPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_CLIENT_SECRET=your_client_secret
SPOTIFY_REDIRECT_URI=http://localhost:4000/auth/callback
APP_URL=http://localhost:5173
PORT=4000
CORS_ORIGIN=http://localhost:5173
VITE_SERVER_URL=http://localhost:4000
bun install
bun run dev- Web app: http://localhost:5173
- API server: http://localhost:4000
- Open http://localhost:5173
- Click New Session and enter a session name and your name
- Complete the Spotify authorization
- On the session page, click the ⚙ settings icon to select your Spotify Connect device
- Share the QR code (or the URL) with guests
- Scan the QR code or open the URL the host shared
- Select the active session
- Search for a song and tap + to add it to the queue
To make the app accessible to other devices on your network, update .env with your machine's local IP:
APP_URL=http://192.168.1.x:5173
CORS_ORIGIN=http://192.168.1.x:5173
VITE_SERVER_URL=http://192.168.1.x:4000
SPOTIFY_REDIRECT_URI=http://192.168.1.x:4000/auth/callback
Also add the new redirect URI in your Spotify app settings. Then start with:
bun run dev:server &
bun run --cwd apps/web vite --hostbun run dev # start web + server
bun run dev:web # web only
bun run dev:server # server only
bun run typecheck # typecheck all packages
bun run format # format with prettier- No database — sessions live in an in-memory
Mapon the server. Restarting the server ends all sessions. - Token refresh — Spotify access tokens are refreshed automatically before every API call if they're within 60 seconds of expiry.
- Polling — now playing updates every 3s, queue every 5s, session list every 10s.