
Self-hosted music streaming with peer-to-peer sharing
Features • Screenshots • Quick Start • Architecture • FAQ • API Reference • Contributing
SoundTime is a self-hosted music streaming platform built with Rust and SvelteKit. Upload your music library, organize it into playlists, and share tracks across instances using peer-to-peer networking powered by iroh (by n0.computer).
Unlike centralized platforms, SoundTime gives you full control over your music. Run it on your own server, connect with other SoundTime instances through encrypted P2P channels, and enjoy a modern, responsive listening experience.
Screenshots coming soon — see Quick Start to try it yourself!
| Layer | Technology |
|---|---|
| Backend | Rust, Axum 0.8, Sea-ORM 1.1, PostgreSQL 16 |
| Frontend | SvelteKit 2, Svelte 5, Tailwind CSS, shadcn-svelte |
| Auth | Argon2id, JWT (jsonwebtoken), tower-governor |
| Audio | Lofty (metadata), Symphonia (decode/waveform) |
| P2P | iroh 0.96 (QUIC), iroh-blobs 0.96 (content-addressed storage) |
| Visualization | D3.js 7 (network graph) |
| Storage | Local filesystem or AWS S3-compatible |
| Deployment | Docker Compose, Nginx reverse proxy |
The fastest way to get SoundTime running on any machine (Linux, macOS, Windows WSL):
curl -fsSL https://raw.githubusercontent.com/CICCADA-CORP/SoundTime/main/install.sh | bash
or with wget:
wget -qO- https://raw.githubusercontent.com/CICCADA-CORP/SoundTime/main/install.sh | bash
This will automatically:
- ✅ Check prerequisites (Docker, Docker Compose, git)
- ✅ Clone the repository to ~/soundtime
- ✅ Generate a secure .env with random secrets
- ✅ Pull multi-arch Docker images (works on x86_64 and Apple Silicon / ARM64)
- ✅ Start all services
Custom install path? Set
SOUNDTIME_INSTALL_DIRbefore running:bash SOUNDTIME_INSTALL_DIR=/opt/soundtime curl -fsSL https://raw.githubusercontent.com/CICCADA-CORP/SoundTime/main/install.sh | bash
If you prefer to set things up manually:
git clone https://github.com/CICCADA-CORP/SoundTime.git
cd SoundTime
# Configure environment
cp .env.example .env
# Edit .env — at minimum, change JWT_SECRET to a random string
# Launch all services
docker compose up
Once started: - 🎵 Frontend: http://localhost:3000 - 🔌 API: http://localhost:8080 - 🌐 Nginx proxy: http://localhost:8880
The first user to register automatically becomes the admin. Open the frontend and create your account to begin the setup wizard.
See the Development Guide for a complete setup walkthrough.
Prerequisites: Rust 1.93+, Node.js 20+, PostgreSQL 16
# Start PostgreSQL
docker compose up postgres -d
# Configure environment
cp .env.example .env
# Backend (terminal 1)
cd backend
cargo run
# Frontend (terminal 2)
cd frontend
npm install
npm run dev
See the Deployment Guide for production setup with SSL, custom domain, S3 storage, and P2P configuration.
SoundTime follows a modular monorepo architecture with a Rust backend organized into 6 specialized crates:
soundtime/
├── backend/
│ └── crates/
│ ├── soundtime-server # Axum HTTP server, routes, auth, middleware
│ ├── soundtime-db # Sea-ORM entities & database connection pool
│ ├── soundtime-migration # 22 database migrations (PostgreSQL)
│ ├── soundtime-audio # Audio metadata, storage, waveform generation
│ ├── soundtime-p2p # P2P networking via iroh (discovery, health, search)
│ └── soundtime-plugin # Plugin system (WASM/extism-based extensions)
├── frontend/
│ └── src/
│ ├── lib/
│ │ ├── components/ # 11 UI components (AudioPlayer, NetworkGraph…)
│ │ ├── stores/ # Svelte 5 rune stores (auth, player, queue)
│ │ └── i18n/ # 5 language packs
│ └── routes/ # 16 SvelteKit pages
├── docker/ # Dockerfiles + Nginx config
├── docs/ # Documentation
└── docker-compose.yml # Full-stack orchestration
┌─────────────┐ ┌──────────────────────────────────────────────┐
│ Browser │────▶│ Nginx (reverse proxy) │
└─────────────┘ └────────┬──────────────────────┬──────────────┘
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ Frontend │ │ Backend │
│ SvelteKit 2 │ │ Axum 0.8 │
│ Port 3000 │ │ Port 8080 │
└─────────────────┘ └────────┬─────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────────▼──┐ ┌───────▼──┐ ┌───────▼──────┐
│ PostgreSQL │ │ Audio │ │ P2P Node │
│ 16 │ │ Storage │ │ iroh/QUIC │
└───────────┘ └──────────┘ └──────┬───────┘
│
┌────────▼────────┐
│ n0.computer │
│ Relay Servers │
└─────────────────┘
For a deep dive, see the Architecture Guide.
| Guide | Description |
|---|---|
| Architecture | System design, crate responsibilities, data flow |
| API Reference | Complete REST API documentation (60+ endpoints) |
| Deployment | Production setup, SSL, S3, environment variables |
| Development | Local dev setup, testing, project structure |
| P2P Networking | iroh protocol, relay servers, content addressing |
We welcome contributions of all kinds! Whether you're fixing a typo, adding a feature, or improving documentation — every contribution matters.
What is SoundTime?
SoundTime is a self-hosted music streaming server. You install it on your own hardware, upload your personal music library, and stream it from anywhere — on desktop, mobile, or any device with a web browser.
How does the P2P network work?
SoundTime uses iroh to establish encrypted QUIC connections between instances. When enabled, your node can discover other SoundTime instances, exchange catalog metadata, and stream tracks directly peer-to-peer — without any central server. All connections go through NAT-traversal relay servers provided by n0.computer.
Is my data encrypted?
Yes. All P2P connections use end-to-end encryption via iroh's QUIC transport. Passwords are hashed with Argon2id (OWASP-recommended). API authentication uses short-lived JWT tokens.
Can I use SoundTime without the P2P features?
Absolutely. P2P is entirely optional. If you don't set the P2P_ENABLED=true environment variable, SoundTime works as a standalone self-hosted music server with no external connections.
What audio formats are supported?
SoundTime supports MP3, FLAC, WAV, OGG, AAC, AIFF and most common formats via Symphonia and Lofty. Uploaded tracks can be transcoded to OPUS at 320/128/64 kbps for adaptive streaming.
How many users / tracks can it handle?
$ claude mcp add SoundTime \
-- python -m otcore.mcp_server <graph>