8f33744f8c8320f1dc5925703acf8c4fe966ffad
The isPlaying subscriber is unselected. Every store write during Vibe's feedback/replan handshake called play() on the element that had just ended. That replayed its final buffered milliseconds until the next source loaded. Gate that subscriber and the seek subscriber on an actual value change, and never resume a finished element. Then close the gap the handshake leaves behind. The engine now drives two <audio> elements. The next track buffers into the idle one 20s early. The handover starts before `ended`, so the round-trip happens under the outgoing tail. With a crossfade, that tail fades out under the new track. With crossfade off, the new track waits in silence and starts the moment the tail ends. Both are configurable under Settings -> Transitions and persist to localStorage. Preload is on and crossfade is 400ms by default. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
muzick
A high-performance, distributed music orchestration and recommendation platform.
Overview
muzick is designed to manage a local music library while providing an "infinite vibe" listening experience. It bridges the gap between a local filesystem and advanced discovery engines through a tiered recommendation architecture.
Tech Stack
Frontend
- Framework: React
- Routing: TanStack Router
- Data Fetching: TanStack Query (with Look-ahead Buffering)
- State Management: Zustand (for Session/Vibe state)
- Styling: CSS Variables (Customizable Themes)
Backend
- Runtime: Node.js / TypeScript
- Framework: Fastify
- Task Queue: BullMQ (via Redis)
- Search: Typesense
Infrastructure & Data
- Database: PostgreSQL (Source of truth for metadata, relationships, and session state)
- Cache/Queue: Redis
- Audio Analysis: Essentia (via Worker processes)
- External Metadata: MusicBrainz, Discogs, LRCLib, Cover Art Archive
Core Concepts
- The Rolling Vibe: A continuous, evolving stream of music that uses a "Rolling Window" of tracks. It interleaves owned library tracks with high-probability "probation" tracks (external discoveries).
- The Dislike Lifecycle: A multi-stage state machine that protects users from accidental deletions while ensuring the library stays clean.
- Tiered Similarity: Instant metadata-based matches, followed by deep audio-feature similarity.
Getting Started
Prerequisites
- Docker & Docker Compose
Running Locally
Vibe uses the same per-user identity convention as the rest of the API:
x-user-id when supplied, otherwise the local default user. Each user's Vibe
session and listening history are isolated from other users.
docker-compose up -d
Description
Languages
TypeScript
95.5%
PLpgSQL
2.4%
CSS
1.4%
JavaScript
0.4%
Dockerfile
0.2%