Linthra is an open-source Android music player for people who keep their music on their own devices or self-hosted servers. It plays local files and streams from your own Jellyfin or Navidrome / Subsonic server. No ads, no tracking, no account.
Point it at your Jellyfin / Navidrome / Subsonic server, or a folder of local files, and it plays from there.
Streaming is the default β nothing downloads unless you ask. Browsing stays fast because the app reads from a local catalog rather than the network, and nothing phones home: no telemetry, no ads, no account.
If you self-host your music and want a straightforward Android player for it, give Linthra a try.
Linthra is early alpha β but already usable for testing today. You can connect a real server, sync your library, stream, cache, cast, and drive it from Android Auto on a real phone. It's not production-stable, it's not on Google Play or F-Droid, and it has honest, documented rough edges (see Roadmap and the per-feature docs). That's exactly why it's a great time to jump in β small contributions land fast and shape where it goes.
On F-Droid: not yet. Preparation is underway, but Linthra hasn't been submitted and isn't on F-Droid β see docs/fdroid-readiness.md.
Real captures from a running build β Now Playing, your Library, and the auto-built Smart mixes:
| Now Playing | Library | Smart mixes |
|---|---|---|
![]() |
![]() |
![]() |
More are in phoneScreenshots/;
the full set and capture notes are in docs/listing-assets.md.
The app icon and the feature-graphic banner (above) are generated from one source
design β not mockups.
- Local library β pick a folder (Storage Access Framework), scan it, browse Songs / Albums / Artists with search. No broad storage permission.
- Self-hosted streaming β connect your own Jellyfin or Navidrome / Subsonic server: test, sign in, sync, and stream. Works over HTTPS / Cloudflare-proxied domains.
- Smart offline cache β tap to download the tracks you want offline; Wi-Fi only by default, with a size limit and "Keep offline" pinning.
- Cast / Chromecast β hand a stream off to a speaker or TV, with device volume control and track metadata (title/artist/album/artwork) on the receiver. Pure-Dart Cast, no Google Play Services. (App-name/logo branding on the receiver needs a custom receiver app β see docs/cast.md.)
- Android Auto β browse your Library, Queue, Playlists, and Favorites from the car screen and tap to play.
- Queue / Up Next β play next, add to queue, reorder, remove, and save the queue as a playlist β without building a playlist first (docs).
- Playlists & favourites β create/edit/reorder/delete playlists; favourite tracks. Both sync with Jellyfin where supported.
- Smart mixes β automatic, Made-by-Linthra collections (Recently added / played, Most played, Favorites, Downloaded, Random, Never played) built from on-device signals that stay on the device (docs).
- Background playback β media notification with lock-screen, Bluetooth, and wired-headset controls, plus shuffle / repeat and synced lyrics.
Each feature has a deep-dive in the docs.
Linthra is not on Google Play or F-Droid. It's distributed as a sideloadable APK from GitHub Releases. Alpha releases are GitHub pre-releases.
Obtainium (recommended) β Obtainium installs straight from GitHub Releases and keeps Linthra updated:
- Install Obtainium.
- Tap Add App and paste the source URL:
https://github.com/thezupzup/linthra - Enable "Include prereleases" β alpha builds are GitHub pre-releases.
- Install the latest release; Obtainium handles updates from then on.
Manual APK β download the .apk from the
latest release, open it on your
phone, and allow "install from unknown sources" if prompted.
Build it yourself β flutter pub get && flutter build apk --debug. Full
setup, CI builds, and release details are in
docs/development.md. In most environments, run
./scripts/setup_flutter.sh then ./scripts/verify_android.sh to get the
pinned Flutter toolchain and run the same checks as CI.
Using Android Auto? Sideloaded media apps only appear after you enable Android Auto's developer "Unknown sources" toggle β a one-time step, detailed in docs/android-auto.md.
Heads up: until release signing is provisioned, some alpha APKs may be debug-signed; if a signature changes, you may need to reinstall.
Linthra is small and friendly β good first contributions are very welcome, and many don't need a single line of code:
- Test with your server β does it work with your Jellyfin? Your Navidrome / Subsonic? Tell us what broke.
- Try Cast β connect a Chromecast / speaker / TV and report device compatibility.
- Test Android Auto β on a head unit or the Desktop Head Unit.
- Capture more screenshots β Downloads with tracks, Android Auto, Cast, or a tablet layout.
- Improve docs β fix a confusing step, add a setup gotcha.
- Report bugs in one tap β Settings β Report a bug builds a secret-free report on your device (no tokens, no passwords); review it, then copy it or open a prefilled GitHub issue. (how it works)
- Improve accessibility β better screen-reader labels and TalkBack support.
- Polish UI/UX β small refinements add up.
- Help future providers β WebDAV / NAS support behind the same interface.
New here? CONTRIBUTING.md walks through setup in two
commands, and the contributor roadmap shows
where help is most useful right now. The
issue tracker has tasks tagged
good first issue and help wanted.
Found Linthra useful? A GitHub star helps others discover it.
Sources sit behind one interface, so the app treats them uniformly:
| Source | Status |
|---|---|
| Local files | β Scan a folder, play directly (SAF, no broad permission) |
| Jellyfin | β Stream, cache, cast, playlists & favourites β docs |
| Navidrome / Subsonic | β Stream, cache, cast (favourites & lyrics are follow-ups) β docs |
| WebDAV / NAS | π Planned β same MusicSource seam |
Linthra is built to respect the people who use it:
- No telemetry, no analytics, no phoning home β nothing leaves your device unless you choose to. Bug reports are built locally and never auto-sent; "Open GitHub issue" only opens your browser to a prefilled, unsubmitted issue.
- No surprise downloads β streaming is the default; downloads are always user-initiated, Wi-Fi only unless you opt in to mobile data.
- Minimal permissions β foreground-service + notification (playback) and internet (your server). No broad storage permission.
- Your secrets stay safe β the server password is used once to get a token, then discarded; the token is encrypted at rest, never logged, and stream URLs are minted only on demand. Token-handling details are in each provider's doc.
Next up: local tag/metadata parsing + album artwork Β· Subsonic favourites, lyrics & cover art Β· full playlist sync Β· album/playlist "download all" + background download manager Β· real connectivity detection for the Wi-Fi gate Β· WebDAV / NAS sources.
Later: local-file lyrics (.lrc/tags), ReplayGain, MPRIS, Linux desktop,
richer Android Auto and Cast.
Honest gaps (no local tag parsing yet, single Jellyfin server, direct-play only, partial playlist sync, optimistic connectivity) are documented per feature.
| Topic | Doc |
|---|---|
| Contributing & setup | CONTRIBUTING.md |
| Where to help (contributor roadmap) | docs/contributor-roadmap.md |
| Codebase tour (where everything lives) | docs/codebase-tour.md |
| Architecture & extension points | docs/architecture.md |
| Development, build & CI | docs/development.md |
| Library browsing & search | docs/library.md |
| Music providers (overview) | docs/providers.md |
| Jellyfin setup | docs/jellyfin.md Β· compatibility Β· sync |
| Streaming, buffering & recovery | docs/streaming.md |
| Queue / Up Next | docs/queue.md |
| Offline cache & downloads | docs/offline-cache.md |
| Cast / Chromecast | docs/cast.md |
| Android Auto | docs/android-auto.md |
| Reporting a bug | docs/reporting-bugs.md |
| Playlists & safe removal | docs/playlists-and-delete.md |
| Smart mixes (automatic playlists) | docs/smart-mixes.md |
| Manual QA checklist | docs/manual-test-checklist.md |
| Release process & signing | docs/release-process.md Β· signing |
| F-Droid readiness | docs/fdroid-readiness.md |
| Google Play readiness | docs/play-store-readiness.md |



