Tauri Mobile
Tauri 2.0 mobile development for iOS and Android, including platform-specific code, mobile plugins, testing on simulators and devices, and app store distribution.
You are an expert in building mobile applications with Tauri 2.0, covering iOS and Android builds, platform-specific code, mobile plugins, and app store distribution. ## Key Points - **Designing desktop-first and porting later**: Responsive design from the start is far easier than retrofitting. Plan for touch and small screens from day one. - **Using desktop-only plugins on mobile**: Not all plugins support mobile. Check plugin documentation for platform support. - **Ignoring mobile lifecycle events**: Mobile apps get suspended, resumed, and terminated differently than desktop apps. Handle these events. - **Testing only in simulators**: Simulators miss real-device issues like memory pressure, slow storage, and actual touch behavior. 1. Enroll in the Apple Developer Program ($99/year) 2. Create App ID in Apple Developer Portal 3. Configure signing certificates and provisioning profiles 4. Set up App Store Connect listing 5. Build with `cargo tauri ios build` 6. Upload via Xcode or Transporter 7. Submit for review 1. Enroll in Google Play Developer Program ($25 one-time) ## Quick Example ```bash # Initialize iOS project cargo tauri ios init # Initialize Android project cargo tauri android init ``` ```bash # Build for iOS (release) cargo tauri ios build # The .ipa file is generated in: # src-tauri/gen/apple/build/arm64/MyApp.ipa ```
skilldb get tauri-skills/Tauri MobileFull skill: 404 linesTauri Mobile — iOS and Android Development
You are an expert in building mobile applications with Tauri 2.0, covering iOS and Android builds, platform-specific code, mobile plugins, and app store distribution.
Core Philosophy
Tauri 2.0 brings the same architecture to mobile: a Rust core process communicating with a webview frontend through typed IPC. On iOS, the webview is WKWebView; on Android, it is Android WebView. Your existing Tauri desktop code can share most of its Rust backend and all of its frontend code with mobile targets, with platform-specific adaptations where needed.
Mobile is not an afterthought bolted onto a desktop framework. Tauri 2.0 was redesigned specifically to support mobile as a first-class target. But mobile platforms have different constraints: smaller screens, touch input, background process restrictions, and app store review requirements. Design your UI responsively from the start, and use platform checks to adapt behavior where desktop and mobile diverge.
Do not expect pixel-perfect parity across platforms. The webview engines differ (WKWebView vs Android WebView vs WebView2), and mobile webviews may lag behind desktop versions in feature support. Test early and often on real devices.
Anti-Patterns
- Designing desktop-first and porting later: Responsive design from the start is far easier than retrofitting. Plan for touch and small screens from day one.
- Using desktop-only plugins on mobile: Not all plugins support mobile. Check plugin documentation for platform support.
- Ignoring mobile lifecycle events: Mobile apps get suspended, resumed, and terminated differently than desktop apps. Handle these events.
- Testing only in simulators: Simulators miss real-device issues like memory pressure, slow storage, and actual touch behavior.
Prerequisites
iOS Setup
# Install Xcode from the App Store, then:
xcode-select --install
# Install CocoaPods (if not using Swift Package Manager)
sudo gem install cocoapods
# Verify iOS targets for Rust
rustup target add aarch64-apple-ios
rustup target add aarch64-apple-ios-sim # For Apple Silicon simulators
rustup target add x86_64-apple-ios # For Intel simulators
Android Setup
# Install Android Studio and set environment variables
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
export ANDROID_HOME="$HOME/Library/Android/sdk"
export NDK_HOME="$ANDROID_HOME/ndk/$(ls $ANDROID_HOME/ndk/ | head -1)"
export PATH="$PATH:$ANDROID_HOME/platform-tools"
# Install Rust Android targets
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
Initializing Mobile Targets
# Initialize iOS project
cargo tauri ios init
# Initialize Android project
cargo tauri android init
This generates platform-specific project files:
src-tauri/
├── gen/
│ ├── apple/ # Xcode project
│ │ ├── MyApp.xcodeproj
│ │ ├── MyApp_iOS/
│ │ │ ├── Info.plist
│ │ │ └── Assets.xcassets
│ │ └── Podfile
│ └── android/ # Android project
│ ├── app/
│ │ ├── build.gradle.kts
│ │ └── src/main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ ├── build.gradle.kts
│ └── settings.gradle.kts
Development Workflow
Running on iOS Simulator
# List available simulators
cargo tauri ios dev --list
# Run on a specific simulator
cargo tauri ios dev --device "iPhone 15 Pro"
# Run on a physical device (requires signing)
cargo tauri ios dev --device "Your iPhone Name"
Running on Android Emulator/Device
# List available devices
cargo tauri android dev --list
# Run on emulator
cargo tauri android dev --emulator
# Run on connected device
cargo tauri android dev --device
Mobile Entry Point
// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
// src-tauri/src/main.rs (desktop only)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}
Platform-Specific Code
Rust Side
#[tauri::command]
fn get_platform_info() -> String {
if cfg!(target_os = "ios") {
"Running on iOS".to_string()
} else if cfg!(target_os = "android") {
"Running on Android".to_string()
} else if cfg!(target_os = "macos") {
"Running on macOS".to_string()
} else {
"Running on desktop".to_string()
}
}
// Platform-specific module
#[cfg(target_os = "ios")]
mod ios {
pub fn configure_keyboard() {
// iOS-specific keyboard handling
}
}
#[cfg(target_os = "android")]
mod android {
pub fn configure_back_button() {
// Android back button handling
}
}
Frontend Side
import { platform } from "@tauri-apps/plugin-os";
const currentPlatform = platform(); // "ios", "android", "macos", "windows", "linux"
function isMobile(): boolean {
const p = platform();
return p === "ios" || p === "android";
}
// Conditional UI rendering
function App() {
if (isMobile()) {
return <MobileLayout />;
}
return <DesktopLayout />;
}
Responsive CSS
/* Base styles (mobile-first) */
.container {
padding: 16px;
max-width: 100%;
}
.sidebar {
display: none;
}
/* Tablet and up */
@media (min-width: 768px) {
.container {
padding: 24px;
max-width: 768px;
margin: 0 auto;
}
}
/* Desktop */
@media (min-width: 1024px) {
.sidebar {
display: block;
width: 250px;
}
.container {
max-width: 1200px;
}
}
/* Safe area insets for iOS notch */
.header {
padding-top: env(safe-area-inset-top);
}
.footer {
padding-bottom: env(safe-area-inset-bottom);
}
Mobile Plugins
Haptic Feedback
// Using platform-specific APIs in Rust
#[cfg(target_os = "ios")]
#[tauri::command]
fn haptic_feedback() {
// Call into iOS UIKit via objc crate
}
#[cfg(target_os = "android")]
#[tauri::command]
fn haptic_feedback(app: AppHandle) {
// Call into Android Vibrator service
}
#[cfg(not(any(target_os = "ios", target_os = "android")))]
#[tauri::command]
fn haptic_feedback() {
// No-op on desktop
}
Biometric Authentication
// Using a biometric plugin (community)
import { authenticate } from "@tauri-apps/plugin-biometric";
async function unlockApp() {
try {
await authenticate("Unlock to continue", {
allowDeviceCredential: true,
});
// Authentication successful
} catch (e) {
console.error("Biometric auth failed:", e);
}
}
Camera and Photos
// Platform-aware media handling
async function capturePhoto() {
if (isMobile()) {
// Use mobile camera plugin
const photo = await invoke<string>("capture_photo");
return photo;
} else {
// Use file picker on desktop
const { open } = await import("@tauri-apps/plugin-dialog");
return open({
filters: [{ name: "Images", extensions: ["png", "jpg"] }],
});
}
}
Mobile Configuration
iOS Info.plist
<!-- src-tauri/gen/apple/MyApp_iOS/Info.plist -->
<dict>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan documents</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access to import images</string>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
</dict>
Android Manifest
<!-- src-tauri/gen/android/app/src/main/AndroidManifest.xml -->
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:usesCleartextTraffic="false"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:screenOrientation="unspecified"
android:windowSoftInputMode="adjustResize">
</activity>
</application>
</manifest>
Building for Distribution
iOS Build
# Build for iOS (release)
cargo tauri ios build
# The .ipa file is generated in:
# src-tauri/gen/apple/build/arm64/MyApp.ipa
Android Build
# Build APK (for sideloading/testing)
cargo tauri android build --apk
# Build AAB (for Play Store)
cargo tauri android build --aab
# Sign the AAB for Play Store
jarsigner -verbose -sigalg SHA256withRSA \
-digestalg SHA-256 \
-keystore my-release-key.jks \
app-release.aab my-key-alias
App Store Submission Checklist
iOS (App Store)
- Enroll in the Apple Developer Program ($99/year)
- Create App ID in Apple Developer Portal
- Configure signing certificates and provisioning profiles
- Set up App Store Connect listing
- Build with
cargo tauri ios build - Upload via Xcode or Transporter
- Submit for review
Android (Play Store)
- Enroll in Google Play Developer Program ($25 one-time)
- Create app listing in Google Play Console
- Generate a signing key
- Build AAB with
cargo tauri android build --aab - Upload to Play Console
- Complete content rating questionnaire
- Submit for review
Testing on Devices
# iOS -- run on device with logging
cargo tauri ios dev --device "iPhone" -- --verbose
# Android -- run on device with logcat
cargo tauri android dev --device
adb logcat | grep -i tauri
# Remote debugging (Android)
# Open chrome://inspect in Chrome to debug the Android webview
# Remote debugging (iOS)
# Open Safari > Develop > [Device Name] > [Page]
Install this skill directly: skilldb add tauri-skills
Related Skills
Tauri Commands
Rust commands with the invoke pattern, argument passing, return types, async commands, error handling, state management, and type safety between Rust and TypeScript in Tauri 2.0.
Tauri Distribution
Distributing Tauri applications including installers for MSI, DMG, AppImage, and deb, auto-update with the built-in updater, code signing for Windows and macOS, CI/CD builds, and cross-compilation.
Tauri Frontend
Frontend integration with Tauri 2.0 including React, Vue, Svelte, and Solid frameworks, Vite configuration, asset handling, window management, multiple windows, and webview communication.
Tauri Fundamentals
Tauri 2.0 architecture, Rust backend with webview frontend, project setup with Cargo and npm, development workflow, and build targets for Windows, macOS, Linux, iOS, and Android.
Tauri Patterns
Common Tauri 2.0 patterns: system tray apps, menu bar apps, file handling, SQLite database integration, IPC communication patterns, background tasks, and single-instance enforcement.
Tauri Plugins
Tauri 2.0 plugin system including official plugins for filesystem, shell, dialog, notification, HTTP, clipboard, updater, and deep-link, plus community plugins and writing custom plugins.