Lavalink-compatible audio server
pure TypeScript Β· no Java Β· no yt-dlp
Features β’ Quick Start β’ Configuration β’ API β’ Sources β’ Performance
Sonata is a drop-in replacement for Lavalink (Java) written entirely in TypeScript. It provides the same REST + WebSocket protocol that Discord bots expect, but with faster startup, lower memory, and native YouTube/SoundCloud/Spotify resolution β no Java runtime or yt-dlp required.
| π§ Audio Playback | PCM β Opus encoding, DAVE/E2EE encryption, real-time mixing |
| π 12 Audio Sources | YouTube (InnerTube), Spotify, SoundCloud, Deezer, Apple Music, Bandcamp, Twitch, Vimeo, NicoNico, Mixcloud, Podcasts, HTTP, Local |
| ποΈ 13 DSP Filters | EQ (15-band), karaoke, timescale, tremolo, vibrato, rotation (8D), distortion, channel mix, low-pass, high-pass, reverb, limiter, volume |
| π¦ Zero Java | Pure Node.js β no JRE, no Maven, no yt-dlp |
| π Plugin System | npm packages, local paths, auto-scan β all with full type support |
| π Performance | ~200ms startup, ~15MB idle, ~30MB with 10 players |
| π Protocol | Lavalink v4 + v3 β works with any lavaclient |
| π Observability | Prometheus metrics, health check, HTML dashboard |
npm install -g @sonata-sdk/server
sonata # start with default config (./config.js)
sonata /etc/sonata/config.js # start with custom confignpx @sonata-sdk/server # run directlydocker build -t sonata .
docker run -p 2333:2333 -v ./config.js:/app/config.js sonatagit clone https://github.com/sonata-sdk/sonata.git
cd sonata
npm install
npm run build
node dist/index.jsnpx tsx src/index.ts # one-shot
npm run dev # watch mode (auto-restart)sonata --build # clones repo, installs deps, compilessonata [config-path]
Options:
-v, --version Show version
-h, --help Show this help
--build Clone repo, install deps, and build from GitHubCopy config.example.js β config.js. Every option is documented inline.
| Section | Description |
|---|---|
server |
Host, port, password, CORS, SSL, dashboard path |
logging |
Level, format (text/json), file transport, colors |
sources |
Toggle each source on/off, set API keys |
lavalink |
API version, session resume, plugin directory |
voice |
UDP mode, encryption fallback, keepalive |
player |
Volume, idle timeout, normalization, auto-leave |
queue |
Max size, history, crossfade, shuffle, loop |
cache |
LRU or Redis, TTL, max entries |
metrics |
Prometheus endpoint |
rateLimiting |
Window, max requests, per-user |
security |
HSTS, content-type enforcement, SQLi/XSS blocking |
plugins |
npm packages, local paths, per-plugin config |
clustering |
Multi-node (coming soon) |
resolving |
Search aliases, retry, fallbacks |
dashboard |
Theme, refresh, player controls |
Deezer requires an
arlcookie for high-quality streaming. Setsources.deezer.arlin config. SOCKS proxy is also supported viasources.deezer.proxy.
| Method | Endpoint |
|---|---|
GET |
/v4/info |
GET |
/v4/stats |
GET / POST / DELETE |
/v4/sessions, /v4/sessions/{id} |
GET |
/v4/sessions/{id}/players |
GET / PATCH / DELETE |
/v4/sessions/{id}/players/{guildId} |
POST |
/v4/sessions/{id}/players/{guildId}/voice |
GET |
/v4/loadtracks?identifier= |
GET / POST |
/v4/decodetrack?track= |
POST |
/v4/decodetracks |
POST / DELETE / PATCH |
/v4/sessions/{id}/players/{guildId}/queue |
GET |
/v4/sessions/{id}/players/{guildId}/history |
GET |
/v4/routeplanner/status |
POST |
/v4/routeplanner/free/address, /v4/routeplanner/free/all |
Legacy /v3/* endpoints are also available for backward compatibility.
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Status, uptime, players, memory |
GET |
/version |
Version, node, platform |
GET |
/dashboard |
HTML admin dashboard |
GET |
/metrics |
Prometheus metrics |
| Input | Resolves To |
|---|---|
https://youtube.com/watch?v=... |
YouTube |
https://open.spotify.com/track/... |
Spotify |
https://soundcloud.com/user/track |
SoundCloud |
never gonna give you up |
All sources (auto-detect) |
ytmixes:VIDEO_ID |
YouTube Mix (recommendations) |
ytplaylist:QUERY |
YouTube playlist search |
| Filter | Description | Range |
|---|---|---|
| Volume | Multiplier with 16-bit clamp | 0% β 1000% |
| Equalizer | 15-band graphic EQ (Β±0.25 gain) | 40Hz β 16kHz |
| Karaoke | Center channel removal | β |
| Timescale | Speed, pitch, rate | 0.5x β 2.0x |
| Tremolo | Amplitude modulation | β |
| Vibrato | Pitch modulation | β |
| Rotation | 8D stereo pan | 0.05 β 0.5 Hz |
| Distortion | Sin/Cos/Tan waveshaping | β |
| Channel Mix | Left/right mixing matrix | β |
| Low Pass | 1-pole low-pass filter | β |
| High Pass | 1-pole high-pass filter | β |
| Reverb | Comb-filter delay with decay | 0β100% mix |
| Limiter | Dynamic range compression | 0β1 threshold |
Apply via PATCH /v4/sessions/{id}/players/{guildId} with { filters: { ... } }.
Example usage:
{
"filters": {
"reverb": { "delay": 0.05, "decay": 0.4, "mix": 0.3 },
"highPass": { "smoothing": 0.1 },
"limiter": { "threshold": 0.95, "attack": 0.002, "release": 0.1 }
}
}Sonata supports plugins via config.js:
plugins: {
npm: ['@sonata-sdk/plugin-lyrics'],
paths: ['./my-local-plugin.js'],
configs: {
'@sonata-sdk/plugin-lyrics': { geniusApiKey: '...' }
}
}Create your own using the @sonata-sdk/plugin-sdk:
import { register } from '@sonata-sdk/plugin-sdk'
export default register({
name: 'my-plugin',
version: '1.0.0',
install(ctx) {
ctx.onTrackStart((guildId, track) => {
ctx.log('info', `βΆ ${track.info.title}`)
})
ctx.registerRoute('GET', '/my-plugin/status', (req, res) => {
res.end(JSON.stringify({ ok: true }))
})
},
})| Metric | Sonata | Lavalink (Java) |
|---|---|---|
| Runtime | Node.js 20+ | JRE 17+ |
| Package size | ~5 MB JS | ~100 MB JAR |
| RAM (idle) | ~15 MB | ~300 MB |
| RAM (10 players) | ~30 MB | ~500 MB |
| Startup time | ~200 ms | ~10 s |
| Dependencies | npm | Maven |
| Docker image | ~150 MB | ~400 MB |
src/
βββ index.ts # Entry point
βββ config/ # Config module loader
βββ server/ # HTTP + WebSocket server / router / middleware
βββ lavalink/ # REST API (v3+v4), WS protocol, session manager
βββ player/ # Player state machine, queue, track encoder, audio streamer
βββ discord/ # Voice connection (Opus + DAVE/MLS encryption)
βββ audio/ # DSP mixer with 13 filters
βββ resolving/ # 12 audio source resolvers
β βββ youtube/ # InnerTube API (5 client profiles)
β βββ soundcloud/ # SoundCloud public API
β βββ spotify/ # Spotify Web API + YouTube mirror fallback
β βββ ... # 9 more sources
βββ cache/ # LRU / Redis track cache
βββ dashboard/ # HTML admin dashboard
βββ metrics/ # Prometheus exporter
βββ plugin/ # Plugin manager + loader
βββ types/ # TypeScript type definitions
~8K lines across 48 files.
npm run typecheck # TypeScript type checking
npm test # Run tests (24 passing)
npm run build # Compile to dist/
npm run dev # Watch mode with auto-reload- @sonata-sdk/server β npm package for the server (binary:
sonata) - @sonata-sdk/plugin-sdk β TypeScript SDK for building Sonata plugins
- sonata-sdk-packages β Monorepo of official Sonata SDK packages
- Docs β Package documentation website