Building Datler for Android needs a toolchain the repository cannot install for you: several gigabytes of installers and environment variables set permanently for your user. The repository brings the rest: Rust’s Tauri crates, the Tauri CLI (@tauri-apps/cli), the mobile entry point in apps/desktop/src-tauri/src/lib.rs, and the generated Android project, which is committed. Rust itself (rustup and cargo) is assumed, since the desktop build needs it too. How the Android build itself works is Distribution.
1. JDK 17
The Android Gradle plugin needs JDK 17; newer JDKs (21, 24, 25) fail. Microsoft’s build or Temurin both work:
winget install Microsoft.OpenJDK.17
It installs to a versioned folder such as C:\Program Files\Microsoft\jdk-17.0.20.101-hotspot.
2. The Android SDK and NDK
The easiest route is Android Studio, whose SDK Manager installs and updates all of it, and which brings the emulator:
winget install Google.AndroidStudio
Open it once, then SDK Manager → SDK Tools, and tick:
- Android SDK Platform-Tools (
adb, to install on a phone and read its logs) - Android SDK Build-Tools
- NDK (Side by side)
- Android SDK Command-line Tools
Under SDK Platforms, one platform: API 34 or newer. Without Studio, winget install Google.AndroidSDK.CommandlineTools installs sdkmanager to drive by hand.
3. Three environment variables
Each is read by a different tool, and each is set permanently, at user scope: a set or export in one shell dies with that shell.
| Variable | Read by | Points at |
|---|---|---|
JAVA_HOME | Gradle, to find the JDK | the folder containing bin\java.exe: the JDK 17 folder from step 1 |
ANDROID_HOME | Tauri and the SDK tools, to find platform-tools, build-tools and platforms | the SDK root, by default C:\Users\<you>\AppData\Local\Android\Sdk |
NDK_HOME | cargo-mobile2, to find the linkers for the *-linux-android Rust targets | one versioned NDK folder, such as ...\Sdk\ndk\27.0.12077973 |
NDK_HOME is the versioned folder, not Sdk\ndk. The NDK installs side by side, so Sdk\ndk\ holds one folder per version and is not an NDK itself; ls $env:LOCALAPPDATA\Android\Sdk\ndk shows the version. What Tauri needs from inside it is the clang wrapper that links each Rust Android target, <NDK_HOME>\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android<api>-clang.cmd. Pointed at the container, that path does not resolve, and the failure arrives late: tauri info reports the NDK missing, or cargo stops with linker not found partway through the first build.
Type the full path, not %LOCALAPPDATA%. Windows expands %VAR% only in values stored as REG_EXPAND_SZ, and some tools in this chain (Gradle, Rust build scripts) read the raw value, so a path with % in it can reach them unexpanded and fail with a nonsense file name.
Set them in Win+R → sysdm.cpl → Advanced → Environment Variables → User variables, or from any shell (setx is a Windows program, so Git Bash works too):
setx JAVA_HOME "C:\Program Files\Microsoft\jdk-17.0.20.101-hotspot"
setx ANDROID_HOME "C:\Users\<you>\AppData\Local\Android\Sdk"
setx NDK_HOME "C:\Users\<you>\AppData\Local\Android\Sdk\ndk\<version>"
Never use setx for PATH: it truncates at 1,024 characters and writes back an expanded copy, which can destroy a PATH for good. Tauri finds adb through ANDROID_HOME, so PATH is optional; to use adb by hand, add ...\Android\Sdk\platform-tools through the dialog.
A process reads its environment when it starts, and never again. Every shell already open keeps the old values, and so does everything it starts, including an editor’s agent session, whose shells inherit from the editor: new variables reach it only once the editor itself restarts. That is the usual reason a toolchain reads as missing minutes after it was installed.
Check them in a new PowerShell:
$env:JAVA_HOME; $env:ANDROID_HOME; $env:NDK_HOME
java -version
ls "$env:NDK_HOME\toolchains\llvm\prebuilt"
All three are set, java -version reports 17, and the last line succeeding proves NDK_HOME is a real NDK rather than the folder of versions.
4. Four Rust targets
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
aarch64 covers almost every real phone; the other three cover older devices and the emulator. tauri android init expects all four.
5. Check
pnpm run tauri info
The Android section lists the SDK, the NDK and the four targets with no warnings. tauri info prints no Android section at all until it finds the SDK and the NDK, so a missing section is the signal, not an error message.
Building
tauri android dev runs on an emulator or a phone with USB debugging; tauri android build makes an APK. The phone’s build is a debug build for one ABI:
JAVA_HOME="C:/Program Files/Microsoft/jdk-17.0.20.101-hotspot" \
pnpm run tauri android build --debug --target aarch64
- No
--beforeandroid. pnpm passes it through, and the Tauri CLI then readsandroidas a stray argument and stops with a usage message. --target aarch64builds one ABI instead of four, a quarter of the work for installing on a particular phone; a universal APK is only for distribution.- Close the dev app first (
pnpm run kill:ports). A runningtauri devholds Cargo’s lock ontarget/, and an Android build started beside it waits on that lock with no output,cargoalive at about 0% CPU.
Traps
JAVA_HOME must be the JDK 17 you installed, never a bundled one. Android Studio ships its own runtime at Android Studio\jbr, which is JDK 25, and may add another at Android\openjdk\jdk-21.x; both are too new for the Android Gradle plugin.
A shell that does not inherit JAVA_HOME finds the wrong JDK. An agent’s Git Bash, CI, or anything started outside the desktop session leaves the Tauri CLI to find a JVM on its own, and it finds Studio’s JDK 25, even though the variable is set correctly for the user. Gradle then fails configuring :buildSrc with a message that is only a version number:
* What went wrong:
A problem occurred configuring project ':buildSrc'.
> 25.0.3
Nothing names Java. The tell is a JDK 24+ warning a few lines earlier, “Restricted methods will be blocked in a future release”, which JDK 17 never prints. A scripted build therefore passes JAVA_HOME explicitly, as in the command above.
Keep the SDK out of Program Files. Studio can be pointed at C:\Program Files (x86)\Android\android-sdk, which needs administrator rights to write, so the SDK Manager’s downloads (the NDK especially) fail or silently do nothing, and whose path contains spaces and parentheses, which the NDK’s own build scripts handle badly. The default %LOCALAPPDATA%\Android\Sdk is writable by you.
Related
Distribution · Architecture Overview · Driving the App (CDP) · Monorepo Layout