🎧 Open source Spotify client that doesn't require Premium nor uses Electron! Available for both desktop & mobile!
Go to file
2026-10-30 19:45:43 +00:00
.github cd(build): add support for building WebView native libraries on Linux and Windows 2026-10-29 16:03:55 +06:00
.opencode feat(ui): integrate LocalTextStyle for dynamic tinting in player controls and UI components 2026-10-15 13:12:39 +06:00
.vscode Merge branch 'master' into dev 2026-10-26 15:23:11 +06:00
assets chore(assets): refresh screenshots, store graphics and Steam hero 2026-10-30 14:43:47 +06:00
buildSrc feat(packaging): Flathub, AUR, WinGet and Chocolatey publishing 2026-10-23 10:08:29 +06:00
composeApp fix(player): smooth the expanded player swipe 2026-10-30 14:16:51 +06:00
gradle fix(build): add headless mode for Linux and update CI to prepare dependencies 2026-10-29 15:01:43 +06:00
iosApp build: upgrade to Kotlin 2.4.21 and Compose Multiplatform 1.12.2 2026-10-23 11:54:29 +06:00
js_plugin_example refactor: move package name from dev.krtirtho to org.spotube 2026-10-16 15:37:15 +06:00
lib/l10n Merge 7b85ab1617 into 08f8f65a2a 2026-10-30 19:45:43 +00:00
metadata chore(assets): refresh screenshots, store graphics and Steam hero 2026-10-30 14:43:47 +06:00
packaging chore(assets): refresh screenshots, store graphics and Steam hero 2026-10-30 14:43:47 +06:00
plugin_interfaces chore: remove devil's name 2026-10-30 10:33:11 +06:00
.dockerignore fix: windows SSL Certificate error breaking login #905 (#1474) 2024-05-04 20:10:19 +06:00
.gitignore feat: integrate Uniffi for audio metadata reading and writing with Lofty library 2026-07-18 00:14:35 +06:00
.gitmodules feat: migration to Compose Multiplatform 2026-06-30 17:00:13 +06:00
.mcp.json feat(ui): integrate LocalTextStyle for dynamic tinting in player controls and UI components 2026-10-15 13:12:39 +06:00
AGENTS.md Merge branch 'dev' into ios-crash-fix 2026-10-26 13:45:32 +06:00
build.gradle.kts feat: integrate Nucleus framework for enhanced window management and webview support 2026-08-14 20:40:37 +06:00
CHANGELOG.md chore: remove devil's name 2026-10-30 10:33:11 +06:00
cliff.toml refactor: move package name from dev.krtirtho to org.spotube 2026-10-16 15:37:15 +06:00
CODE_OF_CONDUCT.md Contribution guidelines added 2022-01-19 22:56:12 +06:00
CONTRIBUTION.md chore: update contact information and library version in project files 2026-10-18 19:23:18 +06:00
gradle.properties ci: remove nightly tag movement from release workflow 2026-10-26 18:11:35 +06:00
gradlew feat: update dependencies and configure compose hot reload settings 2026-08-13 22:03:41 +06:00
gradlew.bat feat: migration to Compose Multiplatform 2026-06-30 17:00:13 +06:00
lefthook.yaml chore: update license information to GNU Affero General Public License 2026-07-23 10:05:14 +06:00
LICENSE feat: migration to Compose Multiplatform 2026-06-30 17:00:13 +06:00
PRIVACY_POLICY.md chore: update contact information and library version in project files 2026-10-18 19:23:18 +06:00
README.md docs: improve formatting and clarity in the documentation 2026-10-30 16:10:00 +06:00
settings.gradle.kts fix: add mavenLocal() to plugin and dependency resolution management 2026-08-15 22:01:56 +06:00

Spotube Logo

A cross-platform extensible open-source music streaming platform.
Bring your own music metadata/playlist/audio-source with plugins created by community or by yourself. A small step towards the decentralized music streaming era!

Visit the website Discord Server

Support me on Patron Buy me a Coffee

HackerNews

Donate to our Open Collective


Spotube Desktop Spotube Mobile

****

🌃 Features

  • 🧩 Plugin powered, supports any platform or custom music service through plugins.
  • 🗺️ Community driven plugins for popular platforms or create your own.
  • ⬇️ Freely downloadable tracks with tagged metadata.
  • 🖥️ 📱 Cross-platform support.
  • 🪶 Small size & less data usage.
  • 🕒 Time synced lyrics regardless of the plugin support.
  • ✋ No telemetry, diagnostics or user data collection.
  • 🚀 Native performance.
  • 📖 Open source/libre software.
  • 🔉 Playback control is done locally, not on the server.

⬇️ Download

Download Spotube from the Official Website: https://spotube.cc

🔄 Nightly Builds

Grab the latest nightly builds of Spotube from the Offical Website.

🕳️ Building from source [Click to expand]


GitHub Workflow Status

Spotube is a Compose Multiplatform app.

1. Prerequisites

  • JDK 21 to run Gradle (the Gradle daemon JDK and GraalVM are provisioned automatically).

  • Rust (rustup + cargo), for the composeApp library built through Gobley.

  • Android SDK, only for Android builds.

  • ComposeNativeWebview, which isn't on Maven Central yet. Clone it at the commit pinned as COMPOSE_WEBVIEW_COMMIT in spotube-release-binary.yml and run ./gradlew publishToMavenLocal in it.

  • Linux only: runtime libraries, including VLC. Needed to run the app, including :composeApp:run:

    Distro Command
    Debian/Ubuntu sudo apt-get install libvlc5 vlc-plugin-base libwebkit2gtk-4.1-0 libgtk-3-0 libasound2 libgl1 libxtst6 libxi6 libxrender1
    Fedora sudo dnf install vlc-libs webkit2gtk4.1 gtk3 alsa-lib mesa-libGL libXtst libXi libXrender (vlc-libs needs RPM Fusion)
    Arch / CachyOS / Manjaro sudo pacman -S vlc webkit2gtk-4.1 gtk3 alsa-lib libglvnd libxtst libxi libxrender
    openSUSE sudo zypper install libvlc5 libwebkit2gtk-4_1-0 libgtk-3-0 libasound2 Mesa-libGL1 libXtst6 libXi6 libXrender1

    On Ubuntu 24.04+/Debian 13, libgtk-3-0 and libasound2 are libgtk-3-0t64 and libasound2t64; apt resolves this itself.

2. Run in development

Desktop (JVM), fastest edit/run loop

./gradlew :composeApp:run

Android debug APK

./gradlew :composeApp:assembleStableDebug

Use ./gradlew :composeApp:assembleNightlyDebug for the nightly channel.

Development builds stay fast: the release-only optimizations below are skipped.

3. Build the desktop app

A native build takes about 10 minutes, uses every CPU core and peaks at ~15 GB of RAM. It only happens for the tasks below, never for run.

Native toolchain (Nucleus downloads GraalVM CE on the first build; set GRAALVM_HOME to use your own):

OS Requirements
Linux gcc, zlib headers, patchelf; rpm for .rpm, fuse + zstd for .AppImage.
Debian/Ubuntu: sudo apt-get install build-essential zlib1g-dev patchelf rpm fuse zstd.
Fedora: sudo dnf install gcc zlib-devel patchelf rpm-build fuse zstd
macOS Xcode Command Line Tools (xcode-select --install)
Windows Visual Studio Build Tools with "Desktop development with C++" (use an "x64 Native Tools" prompt if native-image can't find MSVC)

Build and run the app folder:

./gradlew :composeApp:createGraalvmNativeDistributable

Output folder: composeApp/build/compose/binaries/main/graalvm-app/

Build and launch in one step

./gradlew :composeApp:runGraalvmNativeDistributable

Keep the spotube binary next to the libraries it was built with; it loads them from its own folder.

Installers (each OS builds only its own):

OS Command
Linux ./gradlew :composeApp:packageGraalvmDeb :composeApp:packageGraalvmRpm
Linux (AppImage) ./gradlew :composeApp:packageGraalvmAppImage -PappImage=true
Windows ./gradlew :composeApp:packageGraalvmExe (or packageGraalvmMsi)
macOS ./gradlew :composeApp:packageGraalvmDmg

Output folder: composeApp/build/compose/binaries/main/graalvm-<format>

Tip

Add -Pnightly=true for the nightly channel (separate icons and name).

How the Linux AppImage bundle works
  • DownloadLinuxGtkBundleTask downloads the Ubuntu 24.04 packages (audio-only VLC via vlcj-bundler, GTK 3, WebKitGTK 4.1, glib-networking), keeps only what GTK/WebKit reach and relocates the libraries with patchelf. Needs ar, tar, zstd, readelf, patchelf.
  • WebKitGTK has its helper-process path compiled in, so AppImageEnvironment patches it to a relative path and moves to that directory at startup. It also sets GIO_EXTRA_MODULES and WEBKIT_DISABLE_DMABUF_RENDERER=1 (the bundled WebKitGTK 2.44 never paints against a newer host Mesa).
  • main() must call GraalVmInitializer.initialize() first: the VLC loader and the environment setup read compose.application.resources.dir.

4. Native build breaks, JVM works

A native image is a closed world: everything reached through reflection, JNI or JNA (vlcj, Zipline, NewPipe, ktor, datastore, ...) must be declared at build time. Nucleus generates most of it; the rest lives in composeApp/graalvm/reachability-metadata.json.

Symptoms: ClassNotFoundException, NoSuchMethodException or MissingReflectionRegistrationError in the native binary, while :composeApp:run works.

  1. ./gradlew :composeApp:runWithNativeAgent starts the app on the JVM with GraalVM's tracing agent.
  2. Use the broken feature, then close the window normally. Ctrl+C discards the recording.
  3. Commit the updated JSON in composeApp/graalvm/ and rebuild.

Tip

./gradlew :composeApp:runGraalvmNative is a faster debug loop: a quick -Ob build that names the missing registration.

Warning

Keep the hand-written uk.co.caprica.vlcj.binding.lib.LibVlc entry, or playback fails to initialize.

5. Production vs development builds

Production mode turns on automatically for package*, create*, notarize* and nativeImageCompile tasks. Force it with -Pproduction=true|false.

Area Development Production
Rust lib fast debug profile release with LTO and stripping (31 MB → 1.8 MB)
Desktop app hot-reloadable JVM app size-optimized (-Os) GraalVM native image
Native libs all host OS/CPU only; Skia loaded from lib/; on Linux ~10 KB libjvm.so/libjava.so shims instead of the JDK's 28 MB one

Android picks the Rust profile from its build type.

6. Releases

Run spotube-release-binary.yml manually (workflow_dispatch) as stable, beta or nightly.

  • Beta: the stable build as a draft, tagged v<version>-beta.N. Set betaNumber in composeApp/build.gradle.kts to N, and back to null for stable.
  • Desktop: each platform (Linux x86_64 and aarch64, Windows, macOS) builds its installers on its own runner.
  • Android: a signed APK.

📚 Resources

Core stack

Desktop and native

Plugins

👥 The Spotube team

💼 License

Spotube is open source and licensed under the AGPL-3.0-or-later License.

© Copyright Spotube 2026