Developers

Build the Android app yourself

Build the TRS Launcher APK from source: Android SDK and NDK, Rust targets, debug and release builds, your own signing key and your own app ID.

The Android app is the same Tauri 2 project as the desktop launcher, built for Android. This page is for contributors and for players who want to build and sideload their own APK. If you only want to play, take the signed APK from our website – see Android: install the APK.

What you get: the full app – sign-in, instances, modpacks, social, wardrobe and Minecraft: Java Edition through the built-in game engine with the touch overlay. What you don't get: automatic updates. The app checks our official update channel, but Android only installs an update that has the same package name and the same signing key – your own build has a different key, so you update it by building again.

The commands on this page are the ones the CI uses (.github/workflows/ci.yml and release.yml, jobs Android) plus the local notes from docs/mobile.md in the repository. The CI builds on Linux; local builds are described for Windows. Building the Android app on macOS is not tested.

What is where

PathWhat it is
src-tauri/gen/android/The Gradle project of the app (checked in, minSdk 26 = Android 8.0)
src-tauri/gen/android/app/build.gradle.ktsApp ID, SDK levels, release signing
src-tauri/tauri.android.conf.jsonAndroid overrides of the Tauri config (no desktop updater, no bundled TRS Client jars)
src-tauri/plugins/tauri-plugin-trs-game/android/The game engine (parts of Amethyst/PojavLauncher, ndk-build) and the touch overlay
src-tauri/plugins/tauri-plugin-trs-game/android/prebuilt.lockPrebuilt engine parts that Gradle downloads and checks with SHA-256

Requirements

ToolVersion (as in the CI)
Node.js and pnpmNode 22, pnpm as pinned in package.json (corepack enable)
Ruststable via rustup, targets aarch64-linux-android (phones) and x86_64-linux-android (emulator)
JDK21 (CI: Temurin; the JBR that comes with Android Studio works too)
Android SDKwith cmdline-tools and platform-tools
Android NDK28.2.13676358 for the app (NDK_HOME) and 27.3.13750724 (r27d) for the game engine
Gradlenothing to install – the wrapper in src-tauri/gen/android uses Gradle 8.14.3

The app compiles against Android SDK 36 (compileSdk/targetSdk). In the CI only platform-tools and the two NDKs are installed by hand; the rest comes through the Android Gradle plugin. Accept the SDK licenses once with sdkmanager --licenses.

You need both NDKs. The game engine plugin pins ndkVersion = "27.3.13750724" in its own build.gradle.kts; the Rust part is linked with the NDK from NDK_HOME (28.2).

Build a debug APK

Get the code

git clone https://github.com/theredstonee/TRS-Launcher.git
cd TRS-Launcher
pnpm install

Install the SDK parts and Rust targets

sdkmanager --install "platform-tools" "ndk;28.2.13676358" "ndk;27.3.13750724"
rustup target add aarch64-linux-android x86_64-linux-android

You can also install the two NDK versions in Android Studio (SDK Manager → SDK Tools → NDK (Side by side), tick Show Package Details).

Set the environment

On Windows (PowerShell) or Linux:

$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
$env:NDK_HOME     = "$env:ANDROID_HOME\ndk\28.2.13676358"
$env:JAVA_HOME    = "C:\Program Files\Android\Android Studio\jbr"

On Windows, turn on Developer Mode first – see Troubleshooting.

Build

pnpm tauri android build --apk --debug --target aarch64

This builds the frontend (pnpm generate), the Rust library for arm64 and then the APK with Gradle. The first Gradle run downloads the prebuilt engine parts from prebuilt.lock (checked with SHA-256, cached in ~/.gradle/caches/trs-engine-prebuilt), so it needs internet and takes a while.

Find the APK

The APKs end up under src-tauri/gen/android/app/build/outputs/apk/, in a folder per ABI and build type. The CI doesn't rely on the exact folder name, and you don't have to either:

find src-tauri/gen/android/app/build/outputs/apk -name '*.apk'

Install it on your phone

Turn on USB debugging in the developer options of your phone, connect it and run:

adb install -r path/to/the.apk

Or copy the APK to the phone and open it there, as described in Android: install the APK. A debug APK is signed with the debug key of your Android SDK, so it installs right away.

A debug build and our official app have the same package name but different keys. Android refuses to install one over the other ("App not installed" / "conflicts with an existing package"). Uninstall the other one first – that also deletes its instances and worlds – or give your build its own app ID (see below).

For the emulator

pnpm tauri android build --apk --debug --target x86_64

Start the emulator with -gpu host – with SwiftShader the renderer crashes in its Vulkan check. Minecraft 26.x can't be played in the emulator (its Vulkan lacks the needed extensions and OpenGL hangs there); test those versions on a real phone.

Build a release APK

pnpm tauri android build --apk --target aarch64

That is the release command of the CI without --ci. Release builds are minified with R8. Without a signing key the result is an unsigned APK (…-unsigned.apk) – Android can't install that. Sign it with your own key:

Create a keystore once

keytool -genkeypair -v -keystore my-release.jks -alias my-key \
  -keyalg RSA -keysize 4096 -validity 10000

keytool comes with the JDK. Keep the file and the passwords safe: Android only installs updates of an app that are signed with the same key.

Set the four variables

Gradle signs the release APK itself (signingConfigs in src-tauri/gen/android/app/build.gradle.kts) when ANDROID_KEYSTORE_PATH points to an existing file:

export ANDROID_KEYSTORE_PATH=/path/to/my-release.jks
export ANDROID_KEYSTORE_PASSWORD='…'
export ANDROID_KEY_ALIAS=my-key
export ANDROID_KEY_PASSWORD='…'      # same as the keystore password unless you chose another one

On Windows set them with $env:NAME = "…" like above.

Build and check

pnpm tauri android build --apk --target aarch64
"$ANDROID_HOME"/build-tools/<version>/apksigner verify --print-certs <the.apk>

apksigner shows the SHA-256 of your certificate – not the one listed on the install page, which belongs to our official key.

You don't need any of the project's secrets. The desktop updater key (TAURI_SIGNING_PRIVATE_KEY) only signs the update channel files in the release workflow, and Android builds don't create updater files anyway (tauri.android.conf.json). The CurseForge key is optional, exactly as on the desktop: the environment variable CURSEFORGE_API_KEY or the file ~/.tauri/curseforge-api-key (%USERPROFILE%\.tauri\curseforge-api-key on Windows). Without it the build works and simply hides CurseForge.

Make it your own app

If you want to install your build next to the official app or share it with friends, give it its own app ID and name:

WhatWhereChange
App ID (package name)src-tauri/gen/android/app/build.gradle.ktsapplicationId = "dev.theredstonee.trslauncher" → for example "io.github.yourname.trslauncher"
Name on the home screensrc-tauri/gen/android/app/src/main/res/values/strings.xmlapp_name and main_activity_title
Iconsrc-tauri/gen/android/app/src/main/res/mipmap-*/ic_launcher*.png (the ic_launcher_halloween* files are the event icon)
Signing keyyour own keystoresee above
Change only applicationId – not namespace in the same file and not identifier in src-tauri/tauri.conf.json. The Kotlin package dev.theredstonee.trslauncher is wired into the Rust code (register_android_plugin in src-tauri/src/mobile.rs, the JNI function Java_dev_theredstonee_trslauncher_PushPollWorker_nativePoll in src-tauri/src/push.rs), and the Tauri CLI stops the build with "you have modified your "identifier" in the Tauri configuration" when the identifier no longer matches the Kotlin folder. The engine and push plugins read the package name at runtime, so a new applicationId is fine for them.

What still works in your own build, according to the code:

  • Microsoft sign-in: the app uses Microsoft's device-code sign-in (you type a code on Microsoft's page). It doesn't depend on the package name or a redirect into the app.
  • TRS services (friends, chat, capes, TRS API): the app talks to the same API; there is no check of the package name or signature.
  • Links like trs-launcher://pack/<code> use the same scheme in every build. With the official app and your build installed side by side, Android asks which app should open them.
  • Updates: see the top of the page. The in-app installer only accepts an APK for its own package name, so it can't replace your build with the official one, and Android rejects our APK over a build with your key.

We haven't tested a renamed build ourselves – if something breaks, please report it.

Run the checks

The same checks as the CI job Android:

pnpm generate                       # generate_context! needs the built frontend
cd src-tauri
cargo clippy --workspace --target aarch64-linux-android -- -D warnings
cd gen/android
./gradlew --no-daemon :tauri-plugin-trs-game:testDebugUnitTest   # touch overlay and engine logic, no device

Clippy runs outside tauri android build and needs the NDK compiler for the C parts (SQLite, ring). The CI sets these on Linux:

bin="$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
export CC_aarch64_linux_android="$bin/aarch64-linux-android26-clang"
export AR_aarch64_linux_android="$bin/llvm-ar"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$bin/aarch64-linux-android26-clang"

Troubleshooting

"A required privilege is not held by the client"

On Windows, tauri android build links the Rust library into gen/android/app/src/main/jniLibs with a symbolic link. Without Developer Mode (or admin rights) that fails. Turn on Developer Mode in the Windows settings, or copy the library yourself (src-tauri/target/<triple>/debug/libtrs_launcher_lib.so → jniLibs/<abi>/) and run the Gradle task in src-tauri/gen/android, for the emulator gradlew assembleX86_64Debug.

NDK not found or wrong NDK version

NDK_HOME must point to 28.2.13676358, and 27.3.13750724 must be installed in the SDK's ndk/ folder as well. If your r27d lives somewhere else, set android.ndkPath in src-tauri/gen/android/local.properties or the variable ANDROID_NDK_HOME (see the comment in the plugin's build.gradle.kts).

The SDK setup asks for the package "tools"

The old SDK package tools doesn't exist any more with current cmdline-tools. Install only cmdline-tools, platform-tools and the two NDKs – the CI does the same.

The release APK doesn't install

It is unsigned (…-unsigned.apk). Set the four signing variables and build again, or use a debug build.

"App not installed" or "conflicts with an existing package"

Another build of the app with a different key is installed – often our official app. Uninstall it first (this removes its instances) or give your build its own app ID.

"SHA-256 stimmt nicht" while Gradle downloads the engine parts

A download from prebuilt.lock didn't match its checksum (for example a broken connection or a proxy). The file is thrown away; run the build again.

The game crashes in the emulator or 26.x doesn't start there

Use -gpu host, and test Minecraft 26.x on a real phone (see For the emulator).

The app can't be installed on an older or 32-bit phone

The app needs Android 8.0 and a 64-bit processor: only arm64-v8a and x86_64 are packaged because the game engine exists only for 64 bit.

CurseForge is missing

The build had no CurseForge API key. That's expected for own builds – see the note on the key above.

License and name

TRS Launcher is free software under the GNU General Public License v3.0 (LICENSE, copyright notices in NOTICE). You may build, change and share the app. If you share an APK, the GPL requires that you share it under the same license and make the complete source code of exactly that build available, including your changes. The game engine contains third-party parts with their own licenses (Amethyst/PojavLauncher under LGPL-3.0 and more) – they are listed in NOTICE and must stay in.

The repository has no separate trademark rules. Still: if you hand out your own build, give it its own name and app ID so nobody mistakes it for the official TRS Launcher, and point people to your source code – not to our support.

Next steps

Build the iOS app yourself

The same for iPhone and iPad – needs a Mac with Xcode.

Build from source

The desktop launcher, the checks and the TRS Client mod.
TRS Launcher – The Redstone Launcher by TheRedstonee

Not an official Minecraft product. Not approved by or associated with Mojang or Microsoft.

© 2026 TheRedstonee · GPL-3.0