Skip to content
YossiYadPublic

About

Open-source music client for Invidious and Piped. Vanilla JavaScript PWA with optional self-hosting.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

106 Commits

Folders and files

Repository files navigation

Aura logo

Aura

A music player that just plays music.

Music, podcasts and playlists in an installable web app.
Built with vanilla JavaScript, with optional AI features and self-hosting.

Install on your server

License: AGPL-3.0-only Progressive Web App No build step

Website · Features · Quick start · Install · Self-hosting · Documentation · Contributing

About

Aura is an open-source music client that uses Invidious and Piped instances for search and playback. Find music, build a library, follow podcasts and take saved tracks offline, from your browser or home screen.

The client needs no Aura account and includes no analytics or telemetry. Your library stays on your device by default. For sync, shared listening and server-generated mixes, you can connect it to services you host yourself.

Screenshots

Library Ask AI Shared listening
Aura library with saved tracks Aura AI playlist and voice request screen AuraShare guest queue and voting

Ask AI is shown on a phone with the Hebrew interface setting. Library and shared listening use fictional demo tracks and guest names.

Features

Music and podcasts

Search for songs, artists, albums and playlists. Home builds recommendations from your listening history, while the Podcasts tab organizes shows and their latest episodes. Follow artists and shows to keep them in your library, and resume longer tracks where you left off.

Your library, your playlists

Save favorites, create playlists, choose cover images and reorder tracks. Import public playlists from YouTube, YouTube Music, Spotify or Apple Music. Spotify and Apple Music entries are matched to tracks available through your configured instances.

Browse your library as a grid or list, look back through your listening history and stats, or export your library to a JSON backup you can restore later.

AI playlists and voice requests

Describe what you want to hear, such as "calm instrumentals for studying" or "an upbeat playlist for a road trip". Ask AI suggests songs and matches them to playable tracks. A daily mix offers another starting point based on your listening.

You can also request a song, artist or playlist by voice in Hebrew or English, with commands to play now, play next or add to the queue. Basic named requests work without an AI key. Playlist generation and more complex requests use your own Gemini or Groq key. Voice input depends on browser support; typed requests are also available. On iPhone and iPad, Safari's speech recognizer can miss requests after the first one since the app opened, so Aura also records those requests; if the recognizer heard nothing, the recording is transcribed with your Groq or Gemini key. An artist request plays their songs in a new order each time, and with an AI key it also finds artists whose channel spells the name another way, such as a Hebrew name written in Latin letters.

Offline listening

Save permitted tracks or playlists for playback without a connection. A size-limited cache removes the least recently played downloads when it needs room. Downloads stay on the device that saved them, even when library sync is enabled.

Playback controls

Feature What it does
Queue Reorder tracks, play next, shuffle, repeat and set a sleep timer.
Autoplay Continue with related tracks when the queue ends, with an optional music-only filter.
Audio settings Choose stream quality, adjust crossfade and even out volume between tracks.
AirPlay & Cast Send playback to supported speakers and TVs. See the casting guide.
Lyrics Display available lyrics and search words from lyrics already cached on your device.
SponsorBlock Optionally skip known intros, outros and sponsor segments.
Driving mode Use large playback controls and keep the screen awake where supported.
Private session Pause additions to listening history, stats and recommendations.
Private playlist Mark a playlist for private listening from its menu; what plays from it is never recorded.
Reopening Choose whether the song you left continues where it stopped or starts over when you open the app again.

Language choice

Aura starts in English. On the first launch it asks which language you want, with each option written in its own language, and remembers your answer. You can change it at any time in Settings > Look > Language · שפה. English translates the interface text that otherwise appears in Hebrew; Hebrew preserves the existing mix of Hebrew and English. AI playlist names, questions from voice requests and spoken replies follow the same choice. Song titles, artist names and your own text stay unchanged. Speech recognition has its own language setting. Guests can choose their language on the invitation page too; until they do, it follows their browser.

Accessibility

Settings > Look also has:

  • Text size (Default, Large or Larger) enlarges lists, menus, sheets, dialogs and toasts.
  • High contrast brightens secondary text and outlines. It also turns on automatically when your device asks for more contrast.
  • Animations can be turned off, and motion is reduced when your device asks for it.

Keyboard users get visible focus rings, and Escape closes dialogs and sheets. Screen readers announce toasts and are told which page of the tab bar is showing.

On a computer

Open Aura on a computer and it lays itself out for one: Home and search in a top bar, your library in a column on the left, a "now playing" panel with lyrics on the right, and a full player bar with volume along the bottom. Menus open at the pointer, and the right mouse button opens a song's or a playlist's menu. Phones and tablets keep the phone layout; Settings > Appearance > Layout chooses for a device when you want otherwise.

On Linux and Windows there is also a desktop app: a window and a menu entry of its own, and a tray icon that keeps the music playing with the window closed. A self-hosted installation can offer it from Settings > About, and it signs in through your browser.

Shared listening

On a self-hosted installation, invite guests with a QR code. They can suggest songs and vote from their browser. The host approves participants and chooses whether each person can add tracks freely, submit them for approval, or only view and vote.

Shared playlists let signed-in listeners build a collection together across devices. See shared queue setup for the guest experience and permissions.

Quick start

The frontend is static HTML, CSS and JavaScript. There is no build step or frontend package installation. With Git and Python 3 installed:

git clone https://github.com/YossiYad/aura.git
cd aura
python3 -m http.server 8477

Open localhost:8477. On Windows, you can run start.bat instead with Python or Node.js installed.

To install Aura on your phone, serve it over HTTPS, open it in Safari or Chrome and choose Add to Home Screen. On supported desktop browsers, use the install option. Service workers and offline caching require HTTPS or localhost.

On a computer the same app lays itself out for a wide window: the library in a column on the left, Home and the search field in a top bar, the "now playing" panel on the right and the player bar along the bottom. It switches by itself on a computer - a desktop system with a mouse or a trackpad and a window at least 800 pixels wide - and back again when the window is made narrow. A phone or a tablet keeps the phone layout whatever its size; Settings > Appearance > Layout gives a tablet the computer layout, or a computer the phone's, and the choice stays on that device.

There is also a desktop app for Linux, with a window, a menu entry and a tray icon of its own: see desktop/.

Configure your instances

Without config.json, Aura tries its built-in public instances. Their availability varies; search and playback require a working instance.

To use your own, copy config.example.json to config.json and replace the example address with a reachable instance. A minimal configuration looks like this:

{
  "invidiousInstances": ["https://invidious.example.com"],
  "pipedInstances": [],
  "cobaltInstances": []
}

config.json is git-ignored. An HTTPS-hosted app needs HTTPS endpoints, and instances on another origin must allow browser requests through CORS. The optional textRelay setting requires an actual relay service; a static file server does not provide one.

Self-hosting

Choose the setup that fits your needs. A static host serves the app; an Invidious or Piped instance supplies search results and streams. The full server setup also provides sign-in, sync and shared listening.

The quickest way is INSTALL.md: one block, pasted into a terminal on your server, installs everything in Option 2 below - Invidious included - and sets up HTTPS, on your own domain or, without one, on a free address from Tailscale. The options below explain each step, for doing it by hand.

Option 1: Upload the app to a static HTTPS host
  1. Clone the repository using the quick-start commands above.

  2. Create config.json with the URL of your working HTTPS Invidious instance, as shown under Configure your instances. Use the instance origin, such as https://invidious.example.com, without /api/v1 at the end.

  3. Prepare a directory containing only the frontend and its public configuration:

    mkdir -p .local/site
    cp -R index.html manifest.json sw.js aura.css tokens.css icon.svg icon-180.png icons src guest tv .nojekyll .local/site/
    cp config.json .local/site/config.json
  4. Upload the contents of .local/site/ to your host's web root. For an SSH-accessible server with an existing /var/www/aura directory:

    scp -r .local/site/. user@your-server:/var/www/aura/
  5. Serve that directory over HTTPS. For example, with Caddy, point your domain's DNS at the server, allow ports 80 and 443, and use:

    music.example.com {
        root * /var/www/aura
        file_server
    }
  6. Open your HTTPS address, test search and playback, then add Aura to your home screen.

Only upload the prepared site directory. Backend credentials, .git, .local and selfhost/ do not belong in a public web root. config.json is visible to visitors, so it must contain public client configuration, never secrets.

If your Invidious instance uses a different origin, it must permit CORS requests from the app. Static hosting does not provide /relay, sync, guest queues or nightly mixes. Those require the services in Option 2, or equivalent backend configuration.

Option 2: Run Aura and Invidious on your own server

You need a Linux server, Git, OpenSSL, Docker with a current Compose plugin, a domain, and an HTTPS reverse proxy. The example below uses Caddy on the same server as Docker; an existing nginx or other HTTPS proxy also works. Google sign-in restricts app access. Guest invitation routes are public so invited listeners can join without an account or VPN.

1. Prepare Invidious. From the cloned repository's root, make a local configuration copy so generated secrets stay out of version control:

mkdir -p .local/invidious
cp selfhost/invidious/docker-compose.yml .local/invidious/docker-compose.yml
openssl rand -hex 8
openssl rand -hex 32

Edit .local/invidious/docker-compose.yml:

  • Put the first generated value in both invidious_companion_key and SERVER_SECRET_KEY. The companion requires the same 16-character value in both places.
  • Put the second value in hmac_key.
  • Change the published port to 127.0.0.1:3000:3000. The Aura gateway reaches Invidious on Docker's internal network; the raw HTTP port does not need public exposure.

Start the services with the explicit project name, which creates the network expected by Aura:

docker compose -p invidious -f .local/invidious/docker-compose.yml up -d
curl -f 'http://127.0.0.1:3000/api/v1/search?q=test'

The search request should return JSON. If it fails, inspect docker compose -p invidious -f .local/invidious/docker-compose.yml logs --tail=50. See the Invidious guide and upstream installation documentation for backend-specific troubleshooting. Hosting your own instance does not guarantee that upstream requests will always succeed.

2. Prepare your domain. Point your domain's DNS records at the server, for example music.example.com. Allow inbound TCP ports 80 and 443 through the firewall. If hosting at home, forward those ports on your router to the server; the connection needs a publicly reachable address. Install Caddy on that server, or use your existing HTTPS reverse proxy. The app's internal ports stay bound to loopback.

3. Configure Google sign-in. Follow the Google provider setup to create an OAuth client of type Web application. Register this exact redirect URI, using your own domain:

https://music.example.com/oauth2/callback

Copy the templates and generate a cookie secret:

cp selfhost/private-app/oauth.env.example selfhost/private-app/oauth.env
cp selfhost/private-app/authenticated-emails.example.txt selfhost/private-app/authenticated-emails.txt
openssl rand -base64 32 | tr -- '+/' '-_'

Fill oauth.env with your OAuth client ID, client secret and the generated cookie secret. In authenticated-emails.txt, replace the example addresses with the Google accounts allowed to sign in, one per line. If your OAuth consent screen is in testing, add those accounts as test users in Google Cloud too. Both local files are git-ignored.

4. Start Aura. From the repository root:

PUBLIC_HOST=music.example.com sh selfhost/private-app/setup.sh

Replace music.example.com with your domain. The script writes config.json and .env and builds the services. It saves the hostname for later runs, so updates do not need the variable again. It does not configure your DNS, firewall or HTTPS proxy.

5. Enable HTTPS. Add the following block to /etc/caddy/Caddyfile, using the same domain as PUBLIC_HOST (a template is included):

music.example.com {
    reverse_proxy 127.0.0.1:4180
}

Validate and reload Caddy using its system service:

sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Caddy obtains and renews the HTTPS certificate when the domain and ports are reachable. See Caddy's reverse proxy guide. With another proxy, forward to http://127.0.0.1:4180, preserve the original Host, and set X-Forwarded-Proto: https. If you changed OAUTH_PORT, use that port instead. Always forward through oauth2-proxy. The app's own nginx is not published on the host.

Open https://music.example.com, sign in with an allowed account, test a song and install the PWA from your browser. Listeners only need a browser, with no VPN app. The Google OAuth redirect URI must match this domain exactly.

6. Check and update. Run these from the repository root:

docker compose -f selfhost/private-app/docker-compose.yml ps
docker compose -f selfhost/private-app/docker-compose.yml logs --tail=50

For later updates, run git pull --ff-only, then rerun setup.sh. It regenerates config.json; keep custom configuration in mind before editing that generated file. For service settings, shared queues and optional automatic updates, see the private server guide.

What the server adds

Service What it adds
Library sync Sync playlists, favorites, history, settings and the queue across your devices. Audio downloads remain local.
Shared playlists & queues Collaborate on playlists and invite guests to a listening session.
Push notifications Receive updates for followed artists and podcasts, subject to browser support.
Nightly mixes Prepare a daily mix on your server using an AI key you supply.
Desktop app Build the Linux and Windows desktop app on your server and offer it from Settings, signed in through the browser.

Background playback, voice input and casting depend on the browser and device. On iPhone and iPad, track transitions use sequential playback instead of overlapping crossfade. Custom Google Cast receivers need the additional setup in the casting guide.

Privacy

  • Local storage: library data and settings live on your device; downloaded audio uses the browser cache. Clearing site data removes them, so export a backup first if you want to keep your library.
  • External services: playback, search, artwork, lyrics and sponsor segments make network requests. Some fallbacks use public relays. These services have their own privacy policies; private sessions only affect Aura's local listening records.
  • AI and voice: AI requests go to the provider you configure. Keys are excluded from library sync and backup exports. Browser speech recognition may send audio to its speech service. On iPhone and iPad, a voice request after the first one since the app opened is sent as audio to your Groq or Gemini provider for transcription, only when the built-in recognizer heard nothing. Aura does not save recordings.
  • Your server: optional sync stores library metadata on your server. Server mixes can also send it an AI key; this is enabled by default on self-hosted installations and can be switched off in Settings.

See third-party notices for the services and components Aura uses.

Documentation

Guide Covers
Private server Installation, authentication, sync, notifications and updates.
Invidious Running your own search and playback backend.
AI providers Gemini and Groq setup, key testing, voice transcription on iPhone and connection troubleshooting.
Shared queues QR invitations, guest permissions and host controls.
TV playback AirPlay, Google Cast and custom receiver setup.
Audio interruptions Background playback behavior and device troubleshooting.
Cobalt hosting Optional stream fallback on Hugging Face, with a Koyeb alternative.

Development

The project landing page lives in site/. Its GitHub Pages workflow publishes only the website assets, separately from the music player and server setup.

Aura uses vanilla JavaScript modules loaded by index.html, with a service worker for updates and offline caching. There is no frontend framework or bundler. Optional backend services live under selfhost/.

Each file is a plain script that hands its API to the next through one global on window, loaded in order by index.html. A module that grew too large is split into a folder beside its first file, such as src/views.js and src/views/; its files share window.Aura.<module>, and the first file's header explains how.

File What it owns
src/api.js, src/api/ Instances, search, streams, matching, lyrics, SponsorBlock
src/store.js, src/store/ Everything persisted, and the only thing that writes localStorage
src/player.js, src/player/ The audio element, queue, crossfade, media session
src/cast.js TV receiver connection, artwork, media controls and queue
src/voice.js, src/voice/ Continuous dictation and playback request resolution
src/thinking-orbs/ The AI's thinking orb: the <thinking-orb> element in orbs.js, around the thinking-orbs engine in vendor/
src/views.js, src/views/ Every screen
src/views/desktop*.js, src/desktop.css The desktop layout: its switch, top bar, library column and player bar
src/ai.js Gemini and Groq, key handling, prompts, voice transcription
src/sync.js, src/sync/ Talking to a self-hosted aura-sync
src/shared-queue.js AuraShare on the host's side: the session, guest approvals and QR invitations
src/push.js Web Push subscription
src/nightly.js The daily prep scheduler
src/progress.js The wavy song timeline in the players, driving mode and the TV
src/orientation.js The portrait lock setting
src/log.js The in-app diagnostic log
src/main.js, src/main/ Wiring it together
guest/ The AuraShare page guests open from the QR code
guest/i18n.js The interface language and its English translations, used by the app and the guest page
desktop/ The desktop app: an Electron window around the web app, signed in through the browser
tv/ The custom Google Cast receiver
sw.js Service worker: cache-first shell, offline, background wake-ups

Run the unit and integration suite with Node.js 22 or newer:

npm ci --prefix selfhost/private-app/queue
node --test tests/*.test.js

Browser checks under tests/ use Playwright separately. Changes to audio behavior also need relevant device testing. See CONTRIBUTING.md for development conventions and checks.

Contributing

Bug reports, feature ideas, documentation improvements and pull requests are welcome. Open an issue to report a problem or discuss a larger change, and read the contribution guide before submitting a PR.

For vulnerabilities, follow the security policy and report privately.

License and credits

Copyright (c) 2026 Yossi Yadgar and Aura contributors. Aura's original code is licensed under AGPL-3.0-only. See LICENSE for the full terms.

The animated thinking orb uses thinking-orbs by Jakub Antalik. Third-party components retain their own licenses; full credits and notices are in THIRD-PARTY-NOTICES.md.

Aura is independent of YouTube, Google, Spotify, Apple and the other services named here. This repository does not distribute recordings or a lyrics catalog. Use streaming and offline features only for content you have the right to access and retain, subject to the relevant service terms. The software is provided without warranty, as set out in the license.

About

Open-source music client for Invidious and Piped. Vanilla JavaScript PWA with optional self-hosting.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages