Rediscover the magic of radio.
50,000+ live stations from every corner of the planet, streaming freely.
No account. No ads. Just you and the dial.
Nostu Wavzz is a free, open-source internet radio player that brings back the nostalgia of radio — that feeling of tuning in to a distant city, discovering a new station, and letting the music carry you away.
Built with Tauri v2, React 19, TypeScript, and Rust — fast, lightweight, and cross-platform: Windows, macOS, Linux, and Android.
- 50,000+ stations — full index sourced from the community-run radio-browser.info directory
- Full-text search — press
Ctrl+K/Cmd+Kanywhere, search by name, country, genre, or language - Smart filters — filter by continent, country, tag/genre, or favorites
- Top charts — stations ordered by real click-count popularity
- My Stations — create and manage your own custom station list
- Bottom-sheet player — a persistent mini pill that expands into a full player; swipe left/right to skip between stations, spin the artwork ring while playing
- Mini overlay — a compact floating player that stays visible while browsing the globe or other tabs
- Lock-screen & notification controls — native Android media notification with play/pause/next/previous, artwork, and hardware-button support
- Audio focus — playback pauses automatically when a call or another app takes audio, and resumes when you regain focus
- Auto-resume on reconnect — plug your headphones or reconnect your Bluetooth earbuds and playback picks right back up
- Crossfade — optional smooth volume crossfade (0.5–3s, adjustable) when switching stations
- Stall recovery — automatically retries flaky streams (3 attempts) and reconnects
- Buffering indicator — an inline "Buffering…" banner appears in the player when a stream stalls
- Sleep timer — 15 / 30 / 60 / 90 min, gently fades the volume out before stopping, and survives an app restart
- Volume slider + mute
- Resume your last station on launch
- Offline-first — full station catalog cached locally (IndexedDB in browser, SQLite FTS5 on desktop/Android)
- Background sync — catalog refreshes automatically every 24h
- Web Worker filtering — search & filter run off the main thread; the UI never stutters, even with 50K rows
- Virtualized grid — smooth scrolling through thousands of station cards
- Favicon cache — station logos stored locally with 7-day TTL + LRU eviction
- Data saver mode — skip station-logo downloads on cellular connections
- Favorites — one-tap heart, persisted across sessions
- 10-band equalizer — full parametric EQ with presets (Flat, Bass Boost, Vocal, Jazz, Classical, etc.)
- Bass boost — +10 dB low-shelf filter for punchy low end
- Spatial audio — stereo widening for a more immersive listening experience
- Night mode — dynamic compression that evens out volume spikes for late-night listening
- Buffer presets — low (1.5s), balanced (3s), or high (6s) buffer for different network conditions
- Live visualizer — real-time waveform visualization in the full player
- Interactive 3D Globe — stations plotted as glowing spheres with continent-colored rim lighting and day/night terminator shadow
- Playing station animation — concentric ring waves pulse outward from the currently playing station, colored to match its continent
- Station info on tap — tap any globe dot to see station details and play instantly
- Tooltip hover — hover over any station on the globe for a quick name/bitrate preview
- Play counts — see how many times you've played each station
- Listening time — track total minutes per station
- Top countries — discover which countries you listen to most
- Recently played — quick access to your latest stations with play counts
- Dynamic accent from station art — the app colors itself with the dominant color of the currently playing station's artwork
- Pure black (AMOLED) mode — deep-black backgrounds for OLED screens in dark mode
- Recently played — a one-tap row of your latest stations right on the home screen
- Shimmer skeletons — smooth loading placeholders while the station catalog syncs
- Searchable settings — find any setting instantly; grouped list-cards with a compact / normal / cozy density scale
- Light & dark themes — follow your system, or pick manually
- Uniform card grid — discover tab uses a fixed 2-column layout with consistent card heights
- No accounts, no tracking, no ads
- All data stays on your device
- Streams connect directly to each station's server — audio is never proxied
| Layer | Technology |
|---|---|
| App shell | Tauri v2 (Rust + system WebView) |
| Native media controls | tauri-plugin-media-session (Android/iOS lockscreen & notification) |
| UI | React 19 + TypeScript (strict) |
| Styling | Tailwind CSS v4 + hand-tuned CSS variables |
| 3D globe | react-globe.gl (Three.js / WebGL) |
| State | Zustand |
| Offline DB (native) | SQLite via rusqlite with FTS5 full-text index |
| Offline cache (web) | IndexedDB via idb |
| Async runtime | Tokio |
| Build | Vite 8 |
NostuWavzz/
├── index.html # Web entry point
├── package.json # npm scripts & dependencies
├── vite.config.ts # Vite + Tailwind + React plugins
├── tsconfig.json
│
├── src/ # React frontend
│ ├── main.tsx # React bootstrap
│ ├── App.tsx # Root: boot, filtering, player logic
│ ├── index.css # Global styles (Tailwind + design tokens)
│ │
│ ├── components/
│ │ ├── Header.tsx # Logo, sync status, favorites, theme toggle
│ │ ├── FilterBar.tsx # Search box, continent/tag chips, country select
│ │ ├── StationGrid.tsx # Virtualized card grid + skeleton loading
│ │ ├── StationCard.tsx # Single station card
│ │ ├── RecentRow.tsx # "Recently played" home row
│ │ ├── StationLogo.tsx # Lazy favicon with data-saver support
│ │ ├── GlobeView.tsx # 3D globe with sphere points, rings, day/night, starfield
│ │ ├── PlayerSheet.tsx # Bottom-sheet player with EQ, bass boost, visualizer
│ │ ├── MiniOverlay.tsx # Compact floating player overlay
│ │ ├── AudioVisualizer.tsx # Real-time waveform visualization
│ │ ├── StatsDashboard.tsx # Play counts, listening time, top countries
│ │ ├── MobileTabBar.tsx # Mobile bottom navigation
│ │ ├── SearchModal.tsx # ⌘K quick-search overlay
│ │ ├── StationInfoModal.tsx # Station detail dialog
│ │ ├── SettingsView.tsx # Searchable settings (theme, density, crossfade, data)
│ │ └── Toast.tsx # Notification toasts
│ │
│ ├── lib/
│ │ ├── api.ts # radio-browser.info client, normalizers, continent mapping
│ │ ├── fetchStations.ts # Batch downloader (4 mirrors, 1K/batch, ≤50K)
│ │ ├── filter.ts # Shared filter logic (used by worker + main thread)
│ │ ├── audioEngine.ts # Audio engine: EQ, bass boost, spatial, night mode, crossfade
│ │ ├── eqPresets.ts # Equalizer preset definitions (Flat, Bass Boost, etc.)
│ │ ├── metadata.ts # ICY/Icecast metadata monitor for live track info
│ │ ├── mediaSession.ts # Native Android media-session bridge (tauri-plugin)
│ │ ├── colorExtract.ts # Dominant-color extraction from station artwork (accent theme)
│ │ ├── stationCache.ts # IndexedDB station persistence
│ │ ├── imageCache.ts # IndexedDB favicon cache (LRU, 7-day TTL)
│ │ ├── storage.ts # localStorage helpers (favorites, last-played)
│ │ ├── tauriApi.ts # Tauri IPC wrapper + browser fallback
│ │ ├── useSleepTimer.ts # Sleep timer hook (fades out, survives restarts)
│ │ ├── useTheme.ts # Light/dark/accent theme hook
│ │ ├── useMediaQuery.ts # Responsive media-query hook
│ │ └── utils.ts # escapeHtml, flags, highlight helpers
│ │
│ ├── store/store.ts # Zustand global store
│ ├── types/index.ts # Shared TypeScript types
│ └── workers/filter.worker.ts # Off-main-thread filtering
│
├── src-tauri/ # Rust backend
│ ├── Cargo.toml
│ ├── tauri.conf.json # App identity, window, CSP, bundle
│ ├── build.rs
│ ├── capabilities/default.json
│ ├── icons/ # App icons (all platforms)
│ └── src/
│ ├── main.rs # Entry point
│ └── lib.rs # SQLite + FTS5, 11 Tauri commands, daily auto-sync
│
└── docs/ # Landing page
└── index.html # Professional marketing site
| Tool | Version | Purpose |
|---|---|---|
| Node.js | ≥ 20 | Frontend toolchain |
| Rust | stable (≥ 1.77) | Tauri backend |
| Tauri CLI | npm i -D @tauri-apps/cli v2 |
Build & dev commands |
npm install
npm run dev
# → http://localhost:5173npm install
npm run tauri devnpm run tauri buildBundles land in src-tauri/target/release/bundle/:
- Windows →
.msi,.exe(NSIS) - macOS →
.app,.dmg - Linux →
.AppImage,.deb
One-time setup:
# Rust Android targets
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
# Set environment variables
export ANDROID_HOME="$HOME/Android/Sdk"
export NDK_HOME="$ANDROID_HOME/ndk/<version>"
# Generate the Android project
npm run tauri android initBuild APK:
# Release APK (arm64), signed with the release keystore
npx tauri android build --target aarch64The signed APK lands in src-tauri/gen/android/app/build/outputs/apk/universal/release/.
Target SDK: 36 (Android 16) | Min SDK: 24 (Android 7.0)
Notes:
- Windows requires Developer Mode enabled for the symlink step during Android builds.
- The release build allows cleartext (
http://) audio, since many radio streams aren't HTTPS yet.- Android 13+ will ask for notification permission on first play — this powers the lock-screen media controls.
tauri-plugin-media-sessionis patched (in the Cargo registry copy, pinned to 0.2.4) to auto-resume playback when Bluetooth or headphones reconnect.
| File | Description |
|---|---|
src-tauri/tauri.conf.json |
App id, window size, CSP, bundle icons |
src/index.css |
Design tokens (colors, shadows, radii) |
src/lib/fetchStations.ts |
Mirror list, batch size, station cap |
| Key | Action |
|---|---|
Ctrl / Cmd + K |
Open quick search |
Esc |
Close dialogs |
Space |
Play / pause |
← / → |
Previous / next station |
If you enjoy Nostu Wavzz, consider supporting the author! Your support helps keep the project alive and growing.
MIT — Copyright © 2026 Nostu Wavzz
Station metadata © radio-browser.info contributors (open data).
Audio streams © their respective broadcasters.