Tauri Android Build System#
Blinko's Android app is built with Tauri 2, compiling a React/TypeScript frontend bundled with a Rust backend into a native Android APK. The Android project lives under app/src-tauri/gen/android/ β a Gradle project generated and maintained by the Tauri CLI. No web-to-native conversion tools (e.g., Capacitor) are used; Tauri renders the web UI inside an Android WebView via the androidx.webkit library.
The primary NPM script entry points are defined in app/package.json:
| Script | Command |
|---|---|
tauri:android:dev | tauri android dev --host |
tauri:android:build | tauri android build |
The Tauri app identifier is com.blinko.app and version is managed in tauri.conf.json. The beforeBuildCommand runs bun run build:no-pwa (Vite build with PWA disabled), and the frontend dist is sourced from ../../dist/public .
Gradle Project Structure#
The Android Gradle project at app/src-tauri/gen/android/ uses Gradle 8.9 with Android Gradle Plugin 8.5.1 and Kotlin 1.9.25 . The settings.gradle includes the :app module and delegates further plugin configuration to a Tauri-generated tauri.settings.gradle (generated at build time by Tauri CLI; not committed).
The app-level build.gradle.kts is the main configuration file:
- Application ID / namespace:
com.blinko.app - SDK targets:
compileSdk 34,minSdk 24,targetSdk 34 - Version: pulled from
tauri.propertiesat build time - Plugins:
com.android.application,org.jetbrains.kotlin.android, and the customrustplugin - Tauri hook:
apply(from = "tauri.build.gradle.kts")at line 86 β this file is generated by Tauri CLI at runtime
gradle.properties sets JVM heap to 2 GB (-Xmx2048m) and enables AndroidX.
Custom Rust Gradle Plugin#
The buildSrc/ directory implements a custom "rust" Gradle plugin used to bridge Gradle's build lifecycle with Tauri's Rust compilation step.
RustPlugin.kt registers product flavors and build tasks:
- Creates an
"abi"flavor dimension with auniversalflavor (all ABIs) and individual flavors forarm64,arm,x86,x86_64 - For each flavor Γ build type, creates
rustBuild[Arch][Profile]Gradle tasks (e.g.,rustBuildArm64Release) that hook intomergeJniLibFolders - ABI and target lists can be overridden via Gradle properties
abiList,archList,targetList
BuildTask.kt executes the actual Rust compilation:
- Runs
bun tauri android android-studio-script --target <target> [--release]viaproject.exec - Resolves the Bun executable cross-platform:
bun.exe/bun.cmdon Windows,bunon Unix - Passes
-v/-vvbased on Gradle log level
Build Types and Signing#
build.gradle.kts defines two build types:
Debug:
usesCleartextTraffic = true(for dev server connectivity)- Debug symbols retained for all four ABIs:
arm64-v8a,armeabi-v7a,x86,x86_64 - Minification disabled
Release:
- Signed via
keystore.properties(loaded from the project root), containingkeyAlias,password, andstoreFile - Minification enabled with ProGuard; rules loaded from all
*.profiles plusproguard-android-optimize.txt proguard-rules.proexists as a placeholder; no custom rules are active
Rust / Cargo Configuration#
app/src-tauri/Cargo.toml compiles the Rust crate as staticlib, cdylib, and rlib β all three output types are required for Android JNI linking.
Desktop-only plugins (updater, global-shortcut, single-instance, autostart, clipboard, mouse) are gated with cfg(not(any(target_os = "android", target_os = "ios"))) , so they are automatically excluded from Android builds. Cross-platform plugins (fs, dialog, http, upload, process, opener) are always included.
CI/CD Pipeline (GitHub Actions)#
The publish-android job in .github/workflows/app-release.yml automates the full release build:
Environment setup:
- JDK 17 (Zulu) + Android SDK + NDK
27.0.11902837 - Rust toolchain with all four Android targets:
aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android - Bun 1.2.8
- Gradle cache keyed on
*.gradle*andgradle-wrapper.properties
Key steps:
- Decodes the
UPLOAD_KEYSTOREGitHub secret (base64) and writeskeystore.propertiesatapp/src-tauri/gen/android/keystore.properties - Runs
bun run tauri:android:buildwithNDK_HOMEset - Output APK:
app/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk, renamed toBlinko_<version>_universal.apk - Uploads to GitHub Release via
softprops/action-gh-release
Only the universal flavor is published β not per-ABI APKs.
Key Files Reference#
| File | Purpose |
|---|---|
app/package.json | NPM build scripts entry points |
app/src-tauri/tauri.conf.json | Tauri app config (identifier, version, build hooks) |
gen/android/app/build.gradle.kts | Android module build config (SDK, signing, build types) |
gen/android/build.gradle.kts | Root Gradle build (AGP + Kotlin classpath) |
gen/android/settings.gradle | Module include + Tauri settings hook |
buildSrc/RustPlugin.kt | Custom Gradle plugin: ABI flavors + Rust build tasks |
buildSrc/BuildTask.kt | Gradle task: invokes bun tauri android android-studio-script |
buildSrc/build.gradle.kts | Registers the rust plugin |
gen/android/gradle.properties | JVM heap, AndroidX, Kotlin settings |
app/src-tauri/Cargo.toml | Rust crate config; platform-conditional dependencies |
.github/workflows/app-release.yml | CI pipeline for Android release builds |