Tauri 2 Mobile Development
Build cross-platform mobile apps with Tauri 2 using web technologies (HTML/CSS/JS) for UI and Rust for native backend.
Quick Reference
| Task | Command |
|---|---|
| Init mobile | npm run tauri android init / npm run tauri ios init |
| Dev Android | npm run tauri android dev |
| Dev iOS | npm run tauri ios dev |
| Build APK | npm run tauri android build --apk |
| Build AAB | npm run tauri android build --aab |
| Build iOS | npm run tauri ios build |
| Add plugin | npm run tauri add <plugin-name> |
Workflow Decision Tree
New Project Setup
- •Read references/setup.md for environment configuration
- •Run
npm create tauri-app@latestwith mobile targets - •Configure
tauri.conf.jsonwith app identifier
Adding Features
- •Native functionality: Read references/plugins.md
- •Rust commands/state: Read references/rust-patterns.md
- •Frontend integration: Read references/frontend-patterns.md
- •Authentication/OAuth: Read references/authentication.md
- •In-app purchases: Read references/iap.md
Testing
- •Emulator/ADB debug: Read references/testing.md
- •Use
adb logcat | grep -iE "(tauri|RustStdout)"for logs
Building & Deployment
- •Code signing & stores: Read references/build-deploy.md
- •CI/CD pipelines: Read references/ci-cd.md
Project Structure
code
my-app/ ├── src/ # Frontend ├── src-tauri/ │ ├── Cargo.toml │ ├── tauri.conf.json # Main config │ ├── src/ │ │ ├── main.rs # Desktop entry (don't modify) │ │ └── lib.rs # Main code + mobile entry │ ├── capabilities/ │ │ └── default.json # Permissions │ └── gen/ │ ├── android/ # Android Studio project │ └── apple/ # Xcode project
Essential Configuration
tauri.conf.json
json
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "MyApp",
"identifier": "com.company.myapp",
"bundle": {
"iOS": { "minimumSystemVersion": "14.0" },
"android": { "minSdkVersion": 24 }
}
}
capabilities/default.json
json
{
"identifier": "default",
"windows": ["main"],
"permissions": ["core:default"]
}
lib.rs (Mobile Entry)
rust
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_deep_link::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error");
}
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
Common Issues
| Problem | Solution |
|---|---|
| White screen | Check JS console, verify devUrl, check capabilities |
| iOS won't connect | Use --force-ip-prompt, select IPv6 |
| INSTALL_FAILED_ALREADY_EXISTS | adb uninstall com.your.app |
| Emulator not detected | Verify adb devices, restart ADB |
| HMR not working | Configure vite.config.ts with TAURI_DEV_HOST |
| Shell plugin URL error | Use opener plugin instead (openUrl()) |
| Google OAuth fails | Google blocks WebView; use system browser flow |
| Deep link not received | Check scheme in tauri.conf.json, init plugin |
| Safe area CSS fails on Android | env() not supported in WebView; use JS fallback |
| Windows APK build symlink error | Enable Developer Mode or copy .so files manually |
See references/testing.md for detailed troubleshooting.
Resources
- •Docs: https://v2.tauri.app
- •Plugins: https://v2.tauri.app/plugin/
- •GitHub: https://github.com/tauri-apps/tauri