A free, open-source, world-radio streaming experience delivered as a single codebase across Android, macOS, Windows, Linux and the Web — plus a pixel-perfect marketing site to match.
Projects · Features · Architecture · Quick start · Download · Contributing
Aether Radio is a modern, privacy-first internet-radio client that streams 50,000+ stations from 240+ countries via the Radio Browser community index. One design system, one feature set, five surfaces — and zero compromise on each.
Built on Clean Architecture in pure TypeScript. No frameworks. No analytics. No account. No ads. Every platform ships with song recognition, favorites, history, custom stations, a sleep timer, a real-time audio visualizer and twelve Apple-inspired accent themes.
The repository is a monorepo of five independent projects that share the same domain, use cases and design tokens.
| Project | Folder | Stack | Purpose |
|---|---|---|---|
| 🖥️ Desktop App | DesktopApp/ |
Electron · electron-vite · TypeScript | Native macOS, Windows and Linux app with tray, global media keys, node-shazam-powered recognition and window-state restore. |
| 🤖 Android App | AndroidApp/ |
Capacitor 6 · Android SDK 34 · Kotlin plugin · TypeScript | Native Android app with a custom foreground service, MediaSession notification, background audio and WASM song recognition. |
| 🌐 Web App | WebApp/ |
Vite · TypeScript · Netlify Edge Functions | Browser-native build deployed as a static Vite bundle plus two Edge Functions for CORS-heavy paths. |
| 💎 Landing Site | Landing/ |
Pure HTML · CSS · vanilla JS | Zero-dependency marketing site mirroring the app's design system 1:1. |
| 🎨 Icons | Icons/ |
PNG · SVG · ICNS | Platform-ready app icons for Android, iOS, macOS and the Web. |
Each folder has a standalone README.md with deep architectural notes, build instructions and deployment recipes.
Every platform ships the following feature set, bit-for-bit identical.
|
The full Radio Browser catalogue with a latency-raced multi-mirror client and a transparent failover layer. One-tap favorites with JSON export/import. A rolling history of what you played, when. Shazam-powered "what's playing?" on every platform. PCM is captured from the live stream, hashed locally and matched against the Shazam catalogue. Pick a duration or fade-out curve and the player gracefully stops the stream when the timer hits zero. |
Add your own Icecast, Shoutcast or HLS URL. Stored locally, merged seamlessly with the Radio Browser catalogue. A Web Audio The full Apple Human Interface palette — Blue, Indigo, Royal Purple, Purple, Pink, Red, Orange, Green, Mint, Teal, Cyan, Graphite — plus OS-aware theme detection. Lock screen, notification shade, tray, global media keys, MediaSession, Bluetooth headset buttons. You pick the surface, Aether picks up. |
All three app projects follow the same Clean Architecture layering. Only the infrastructure adapters change between platforms.
┌──────────────────────────────────────────────────────────────────┐
│ Presentation │
│ • Sidebar / BottomNav · PlayerBar / MiniPlayer · Views · Router │
└────────────────────────┬─────────────────────────────────────────┘
│ EventBus + Stores (Singletons)
┌────────────────────────▼─────────────────────────────────────────┐
│ Application │
│ • Use cases (Search, GetTop, AddFavorite, RecognizeSong, …) │
│ • DTOs · Result<T> type │
└────────────────────────┬─────────────────────────────────────────┘
│ Repository interfaces
┌────────────────────────▼─────────────────────────────────────────┐
│ Domain │
│ • Entities · Value objects · Repository contracts │
│ • Pure TypeScript — zero runtime dependencies │
└────────────────────────┬─────────────────────────────────────────┘
│
┌────────────────────────▼─────────────────────────────────────────┐
│ Infrastructure (platform-specific adapters) │
│ ┌──────────────┬──────────────┬──────────────┐ │
│ │ Electron │ Capacitor │ Web │ │
│ │ electron- │ Preferences │ localStorage │ │
│ │ store + IPC │ plugin │ │ │
│ └──────────────┴──────────────┴──────────────┘ │
│ RadioBrowserApiClient · MultiSourceStationRepository │
└──────────────────────────────────────────────────────────────────┘
- Domain-first.
src/domainhas zero dependencies on anything else. Entities (RadioStation,Favorite,PlayHistory,AppSettings,CustomStation), value objects (Country,Genre,BitrateRange) and repository interfaces live there. - Use cases for every action.
SearchStationsUseCase,AddFavoriteUseCase,RecognizeSongUseCase, … Thin, testable, swappable. - Result<T> over thrown exceptions. Errors travel through typed
Result<T>envelopes end-to-end — the presentation layer handles both branches deterministically. - Latency-raced Radio Browser mirrors. The German, Dutch and Austrian mirrors are raced on first API call; the fastest wins, with automatic failover per request.
- Single design system, three shells. Tokens, typography, animations, component styles and twelve accents are copy-pasted across all three apps — one source of truth, one pull request to restyle everything.
Prerequisites: Node.js 20+, npm, and the platform-specific SDKs described in each project's README.
# Clone
git clone https://github.com/MbarkT3STO/Aether-Radio.git
cd Aether-Radio
# Desktop (Electron)
cd DesktopApp && npm install && npm run dev
# Web (Vite)
cd ../WebApp && npm install && npm run dev
# Android (Capacitor)
cd ../AndroidApp && npm install && npm run build && npm run cap:sync && npm run cap:open
# Landing (static — no build)
cd ../Landing && python3 -m http.server 8080Prebuilt binaries and installers for v1.1.0 are available on the GitHub Releases page.
| Platform | Format | Download |
|---|---|---|
| Android | .apk (direct install) |
Aether.apk |
| macOS | .dmg (Apple Silicon) |
Aether.Radio-1.1.0-arm64.dmg |
| macOS | .dmg (Intel) |
Aether.Radio-1.1.0.dmg |
| Windows | Setup (Installer) | Aether.Radio.Setup.1.1.0.exe |
| Windows | Portable .exe |
Aether.Radio.1.1.0.exe |
| Linux | .AppImage |
Aether.Radio-1.1.0.AppImage |
| Web | Browser app | aether-live.netlify.app |
- 🎵 Song Recognition — Identify what's playing on air with one tap
- 🌙 Sleep Timer — Gentle fade-out after a set duration
- 🎙️ Stream Recording — Capture live radio to your device
- 📻 Custom Stations — Paste any stream URL
- 🌐 Web App Launched — Full feature parity in the browser
- 🎛️ Equalizer & Audio Enhancements — Crossfade, buffer management
- 🖥️ Custom Window Controls — Native-feeling title bar on Windows
- ⚡ Performance Optimizations — Reduced CPU usage, skeleton loading, micro-interactions
| Layer | Technology |
|---|---|
| Language | TypeScript 5.4 (strict, isolated modules) |
| Bundler | Vite 5 (Web · Android · Electron renderer) · electron-vite (Electron main + preload) |
| Desktop runtime | Electron 31 · electron-builder 25 · electron-store 8 |
| Mobile runtime | Capacitor 6 · AndroidX Media · Gradle 8 · Kotlin plugins |
| Web runtime | HTMLAudioElement · Web Audio API · MediaSession · Wake Lock · Netlify Edge Functions (Deno) |
| Radio catalogue | Radio Browser Community API (3 mirrors, latency-raced) |
| Song recognition | node-shazam (desktop) · shazamio-core WASM + Shazam signature proxy (Web + Android) |
| Styling | Hand-rolled CSS design tokens · 12 accent palettes · Apple HIG typography · flag-icons |
| Icons | Inline SVGs · platform icon sets in /Icons |
- No accounts, no analytics, no telemetry.
- Favorites, history, custom stations and settings live on-device (electron-store / Capacitor Preferences / localStorage).
- The only outbound traffic is to the Radio Browser mirrors (for station metadata) and to upstream stream hosts (for audio).
- Song recognition is opt-in per tap; audio samples never leave the device except as a short, hashed signature sent to Shazam's public API.
Aether-Radio/
├── AndroidApp/ ← Capacitor-based Android app
├── DesktopApp/ ← Electron app (macOS · Windows · Linux)
├── WebApp/ ← Browser app + Netlify Edge Functions
├── Landing/ ← Marketing site (static, no build)
├── Icons/ ← Platform icons (Android · iOS · macOS · Web)
├── .github/
│ ├── workflows/ ← CI for Android debug + signed release
│ └── ANDROID_SETUP.md ← Keystore + secrets instructions
├── .gitignore
└── README.md ← you are here
Contributions, bug reports and feature requests are welcome. A good starting point:
- Fork the repo and create a feature branch.
- Read the
README.mdof the project you want to touch — each has setup notes. - Keep the domain and use-case layers platform-agnostic.
- Match the existing design tokens rather than introducing new colors.
- Run
npm run typecheckin the affected project before opening a PR.
MIT — do what you want, just keep the copyright notice. Built with ♥ by MBVRK.
- Radio Browser — the community-run station index that powers the catalogue.
- Shazam — for the public song-recognition API surface.
shazamio-core— WASM signature generation used by the Web and Android builds.node-shazam— used by the desktop build.flag-icons— the country flag set.- Apple — for the HIG-derived palette and materials that inspired the design language.
Made with care. Listen to the world, beautifully.