Skip to content

lilremark/Nebula-Music

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

133 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nebula Music logo

Nebula Music

A polished, self-hosted web player for Subsonic and OpenSubsonic music libraries.

Stream from Navidrome, Gonic, Airsonic, and other compatible servers through a responsive interface built for desktop and mobile.

Version React TypeScript Vite Docker License

Features · Screenshots · Quick Start · Docker · Contributing


Screenshots

Nebula Music home dashboard

Nebula Music home view with the now-playing sidebar Nebula Music full-screen player
Now-playing sidebar and queue Full-screen player

Features

Playback

  • Shared app-wide audio engine with queue, repeat, seek, volume, and Media Session controls
  • Per-track playback speed and pitch controls with pitch-correction support
  • Resilient Subsonic streaming with bounded URL caching and stalled-stream recovery
  • Automatic transcoding rules for browser-sensitive formats such as ALAC and M4A
  • Internet radio playback for direct streams and HLS playlists

Listening Experience

  • Web Audio visualizers including Bars, Wave, Circle, Mirror, Spectrum, Particles, Hexagon, Cube, and Grid
  • Expandable full-screen player, desktop sidebar player, floating mini-player, and mobile player bar
  • Structured and synchronized lyrics with fallback lyric providers
  • AutoEq headphone calibration profile search and application
  • Configurable keyboard shortcuts and an immersive Zen mode

Library and Discovery

  • Browse artists, albums, songs, playlists, favorites, and genres
  • Spotlight-style search across artists, albums, and tracks
  • Featured albums, random mixes, recent releases, and most-played statistics
  • Persistent sorting and filtering by genre, year, and library metadata
  • Demo mode for exploring the interface without connecting a server

Platform

  • Subsonic API 1.16.1 with fallback negotiation through API 1.14.0
  • OpenSubsonic extension discovery and structured lyrics v2 support
  • ID3-first album and starred endpoints with legacy server fallbacks
  • Password token/salt authentication and optional OpenSubsonic API-key authentication
  • Responsive light and dark themes with system-preference detection
  • IndexedDB caching for API responses, settings, credentials, and local play statistics
  • Docker, Vercel, and static-hosting deployment options

Compatibility

Nebula Music supports servers implementing the Subsonic API or compatible OpenSubsonic extensions, including:

The music server must be reachable from the browser running Nebula. HTTPS and correct CORS configuration are strongly recommended.

Quick Start

Prerequisites

  • Node.js 20.19+ or 22.12+; Node.js 24 LTS is recommended
  • npm
  • A reachable Subsonic-compatible server, unless using demo mode

Local Development

git clone https://github.com/lilremark/Nebula-Music.git
cd Nebula-Music
npm install
npm run dev

Open http://localhost:3000. No environment variables are required.

Choose one of the supported authentication methods:

  • Password: Enter the server URL, username, and password. Nebula stores the generated token and salt instead of the raw password.
  • API key: Enter the server URL and OpenSubsonic API key. Nebula omits the username and legacy token parameters as required by the extension.

Production Build

npm run typecheck
npm run build
npm run preview

The production bundle is written to dist/.

Docker

The published image is available from Docker Hub as lilremark/nebula-music. It serves Nebula through an unprivileged NGINX 1.30.3 container. The Compose setup uses a read-only filesystem, drops Linux capabilities, and includes a health check.

Pull and run the latest release:

docker pull lilremark/nebula-music:latest
docker run -d \
  --name nebula-music \
  --restart unless-stopped \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=16m \
  --security-opt no-new-privileges \
  --cap-drop ALL \
  -p 8080:8080 \
  lilremark/nebula-music:latest

Open http://localhost:8080.

To stop the container:

docker stop nebula-music
docker rm nebula-music

Using the included Compose configuration:

docker compose -f docker/docker-compose.yml up -d
docker compose -f docker/docker-compose.yml down

Compose uses latest by default. Set NEBULA_VERSION=2.1.3 to pin the current release. See docker/README.md for local-build commands and additional deployment details.

Configuration and Storage

Nebula is a client-side application. Server details and preferences are entered in the UI and stored in the browser.

Storage Contents
IndexedDB Settings, cached API responses, authentication data, and per-server play statistics
localStorage Lightweight play-history snapshots and the last-seen application version

To reset the application completely, clear the site data for the Nebula origin in your browser.

Keyboard Shortcuts

Action Default
Play or pause Space
Previous track ArrowLeft
Next track ArrowRight
Toggle repeat L
Cycle visualizer V
Toggle Zen mode Z

Shortcuts can be changed in Settings.

Architecture

Nebula-Music/
├── components/          Reusable UI, navigation, radio, and player components
├── constants/           Equalizer presets and shared constants
├── context/             Global store and theme state
├── docker/              Docker, Compose, and Nginx configuration
├── hooks/               Adaptive color, artist image, and waveform hooks
├── public/              Static browser assets and audio worklets
├── services/            Subsonic API, AutoEq, and IndexedDB services
├── screenshots/         README product screenshots
├── views/               Home, browse, library, radio, search, and settings views
├── App.tsx              Application shell and view routing
├── index.tsx            React bootstrap
└── index.css            Global styles and theme variables

Data Flow

flowchart LR
    UI["React views and components"] --> Store["Context store"]
    Store --> API["Subsonic service"]
    Store --> Audio["HTMLAudioElement and Web Audio API"]
    API --> Server["Subsonic/OpenSubsonic server"]
    API <--> Cache["IndexedDB cache"]
    Audio --> Session["Media Session API"]
    Audio --> Visualizer["AnalyserNode visualizers"]
Loading

The global store coordinates library requests, cached responses, playback state, and UI updates. A shared HTMLAudioElement handles playback while a lazily created Web Audio graph powers analysis, visualizers, pitch processing, and equalization.

Scripts

Command Description
npm run dev Start the Vite development server on port 3000
npm run typecheck Run TypeScript validation without emitting files
npm run build Create the production bundle
npm run preview Preview the production build locally

Deployment

Vercel

  1. Import this repository into Vercel.
  2. Select the Vite framework preset.
  3. Use npm run build as the build command.
  4. Use dist as the output directory.

Other Static Hosts

Build the project with npm run build, then deploy the generated dist/ directory to Netlify, Cloudflare Pages, Amazon S3, or another static host.

Because Nebula connects directly from the browser, the deployed origin must be permitted by the music server's CORS policy.

Troubleshooting

Nebula cannot connect to my server
  • Verify that the URL includes https:// or http://.
  • Confirm the server is reachable from the same browser and network.
  • Check the server's CORS configuration.
  • Avoid mixed content: an HTTPS deployment cannot call an HTTP music server.
  • Confirm the selected password or API-key authentication mode is supported by the server.
Audio plays but seeking does not work
  • Confirm the server supports byte-range requests and returns appropriate Content-Length and Accept-Ranges headers.
  • Enable server-side transcoding for formats the browser cannot seek reliably.
Settings or themes do not persist
  • Ensure the browser is not blocking IndexedDB or local storage.
  • Clear the site's stored data after changing between demo and live-server credentials.

Changelog

v2.1.3 — June 20, 2026

  • Updated all npm dependencies, including React 19, Vite 8, Tailwind CSS 4, TypeScript 6, Motion 12, and Lucide React 1.
  • Added OpenSubsonic extension discovery and API-key authentication.
  • Added structured lyrics v2 and ID3-first album/starred endpoints with legacy fallbacks.
  • Added Subsonic protocol fallback negotiation from API 1.16.1 through 1.14.0.
  • Centralized Subsonic response and error handling.
  • Updated Docker builds to Node.js 24 LTS and unprivileged NGINX 1.30, with a read-only runtime, dropped capabilities, and container health checks.
  • Published multi-platform 2.1.3 and latest images to Docker Hub at lilremark/nebula-music.
  • Added refreshed product screenshots and updated project documentation.

v2.1.2 — May 10, 2026

  • Added AutoEq headphone calibration.
  • Added production Docker and Nginx deployment files.
  • Improved long-session Subsonic playback recovery.
  • Refined visualizer controls and Settings layout.

See the commit history for the complete development history.

Contributing

Issues and pull requests are welcome. Read CONTRIBUTING.md for development requirements, validation commands, and pull-request guidance.

Security vulnerabilities must not be reported publicly. Email remark@remark.rip and follow SECURITY.md.

License

Distributed under the MIT License.