openjutsu
One-click character swap for videos: an open-source, local Higgsfield Genjutsu alternative built on ComfyUI and MiniMax H3, with FLUX.3 Klein relighting.
Open source, extensible, and native. No tracking, no premium, just your music.
MediaKotlin · MustacheGitHub @team-spotubeOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
🎧 Open source music streaming app! Available for both desktop & mobile!
Taken from the repository README
Loading the full README.
Read the full README ↗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!
****
Download Spotube from the Official Website: https://spotube.cc
Grab the latest nightly builds of Spotube from the Offical Website.
Spotube is a Compose Multiplatform app.
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.
Desktop (JVM), fastest edit/run loop
./gradlew :composeApp:run
Android debug APK
./gradlew :composeApp:assembleStableDebug
Use
./gradlew :composeApp:assembleNightlyDebugfor the nightly channel.
Development builds stay fast: the release-only optimizations below are skipped.
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=truefor the nightly channel (separate icons and name).
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.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.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.
./gradlew :composeApp:runWithNativeAgent starts the app on the JVM with GraalVM's tracing agent.composeApp/graalvm/ and rebuild.[!Tip]
./gradlew :composeApp:runGraalvmNativeis a faster debug loop: a quick-Obbuild that names the missing registration.
[!Warning] Keep the hand-written
uk.co.caprica.vlcj.binding.lib.LibVlcentry, or playback fails to initialize.
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.
Run spotube-release-binary.yml manually
(workflow_dispatch) as stable, beta or nightly.
v<version>-beta.N. Set betaNumber in
composeApp/build.gradle.kts to N, and back to null for stable.Core stack
Desktop and native
Plugins
Spotube is open source and licensed under the AGPL-3.0-or-later License.