Salta al contenuto principale

05 - Tauri mobile (Android + iOS): roadmap

Tauri 2 su Android e iOS: che cosa è supportato oggi, ambiente di sviluppo, plugin disponibili, configurazione, pacchetti per gli store e limiti dichiarati.

Cosa ne pensi di questo articolo?

05 - Tauri mobile (Android + iOS): roadmap
Tauri Rust DesktopFoto:Stanislav KondratievPexels

In Breve

Tauri 2 su Android e iOS: che cosa è supportato oggi, ambiente di sviluppo, plugin disponibili, configurazione, pacchetti per gli store e limiti dichiarati.

Portare un'app Tauri sul telefono: che cosa è supportato oggi

Hai un'app desktop in Tauri e ti chiedi se puoi portarla su Android e iOS senza riscriverla. La risposta breve, secondo la documentazione consultata il 2026-11-13, è che il supporto mobile fa parte di Tauri 2 dalla versione stabile del 2 ottobre 2024: non è più una promessa futura. Il core resta Rust, l'interfaccia resta una WebView, e i sottocomandi tauri android e tauri ios affiancano tauri dev e tauri build nelle fasi di avvio e di compilazione. I limiti sono concreti: non tutti i plugin ufficiali funzionano su telefono, l'updater è solo desktop, per iOS serve un Mac e la costruzione automatica con tauri-action è ancora marcata come sperimentale.

Una precisazione sul titolo e su ciò che ho provato. La documentazione non pubblica una roadmap con date, e questo articolo riporta lo stato attuale, non previsioni. Non ho costruito nessuna app mobile: sulla macchina di scrittura non ci sono Rust, Android SDK né Xcode. Ho eseguito la sola configurazione di Vite mostrata più sotto, ho validato tauri.conf.json contro lo schema ufficiale e ho letto la documentazione, il riferimento della CLI e le guide di distribuzione. Gli altri listati sono schemi da adattare. Prima di questo articolo conviene aver letto la distribuzione su desktop, perché firme e store seguono la stessa logica.

Come funziona Tauri su mobile

L'architettura è la stessa del desktop: un core in Rust e un'interfaccia web. La WebView è quella del sistema: su Android la WebView di sistema, basata su Chromium, la cui versione dipende dal fornitore di WebView scelto sul dispositivo; su iOS, WebKit. Il codice Rust viene compilato come libreria e caricato dal progetto nativo: la guida di sviluppo spiega che Tauri aggiunge all'Xcode project una fase di build che esegue la CLI per compilare i sorgenti Rust. Per la parte nativa il progetto ha scelto Kotlin su Android e Swift su iOS, come scrive l'annuncio della versione 2.0.

Il punto d'ingresso, uguale su tutte le piattaforme
// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

L'attributo cfg_attr(mobile, tauri::mobile_entry_point) è l'unica cosa che distingue un progetto pronto per il telefono: quando la compilazione ha come bersaglio Android o iOS (il cfg mobile), run diventa il punto d'ingresso invocato dal progetto nativo; sul desktop l'attributo non fa nulla. Per questo il builder sta in una funzione pubblica run dentro lib.rs, che il progetto nativo può richiamare. Il resto, cioè i comandi e i tipi che viaggiano fra Rust e interfaccia, funziona come nell'articolo sui tipi condivisi.

Preparare l'ambiente

Gli strumenti sono pesanti e vanno installati una volta. La guida ai prerequisiti li separa per sistema.

Prerequisiti per Android e iOS (schema da adattare, non eseguito)
# --- Android (Linux; su macOS e Windows cambiano i percorsi) ---
# 1. installa Android Studio, poi dal suo SDK Manager:
#    Android SDK Platform, Platform-Tools, NDK (Side by side), Build-Tools, Command-line Tools
export JAVA_HOME=/opt/android-studio/jbr
export ANDROID_HOME="$HOME/Android/Sdk"
export NDK_HOME="$ANDROID_HOME/ndk/$(ls -1 $ANDROID_HOME/ndk)"
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

# --- iOS (solo macOS, con Xcode completo e non i soli Command Line Tools) ---
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
brew install cocoapods

Per Android installi Android Studio e, dal suo SDK Manager, SDK Platform, Platform-Tools, NDK (Side by side), Build-Tools e Command-line Tools. JAVA_HOME punta al JDK incluso in Android Studio, ANDROID_HOME alla cartella dell'SDK e NDK_HOME alla versione di NDK installata (l'espressione con ls prende l'unica cartella presente: se ne hai più di una, scegli tu). I quattro target Rust coprono le architetture dei dispositivi e degli emulatori. Per iOS serve Xcode completo, non soltanto gli strumenti da riga di comando, più CocoaPods; lo sviluppo iOS è disponibile solo su macOS.

Il primo avvio sul simulatore e sul dispositivo

I comandi seguono la forma del desktop. init crea il progetto nativo, dev compila ed esegue con ricarica a caldo dell'interfaccia.

Creazione del progetto nativo e avvio in sviluppo (schema da adattare, non eseguito)
# Android: crea il progetto nativo, poi avvia su un dispositivo collegato o chiede quale emulatore usare
npm run tauri android init
npm run tauri android dev

# iOS (solo macOS): stesso schema, con il simulatore scelto per nome
npm run tauri ios init
npm run tauri ios dev 'iPhone 15'

# iOS su dispositivo fisico: la CLI propone l'indirizzo da usare per il server di sviluppo
npm run tauri ios dev -- --force-ip-prompt

Per impostazione predefinita dev prova a usare un dispositivo collegato e, se non lo trova, ti chiede quale simulatore avviare; passando il nome del dispositivo ('iPhone 15') scegli in anticipo. Se vuoi lavorare con Android Studio o Xcode, aggiungi --open e lascia vivo il processo della CLI finché l'IDE è aperto. Per un iPhone fisico c'è un vincolo in più: il server di sviluppo non può ascoltare solo su localhost, perché il telefono deve raggiungerlo in rete, e la CLI espone l'indirizzo da usare nella variabile TAURI_DEV_HOST.

Configurazione di Vite per il server di sviluppo mobile (eseguita con Node 24)
import { defineConfig } from 'vite';

const host = process.env.TAURI_DEV_HOST;

export default defineConfig({
  clearScreen: false,
  server: {
    host: host || false,
    port: 1420,
    strictPort: true,
    hmr: host
      ? {
          protocol: 'ws',
          host,
          port: 1421,
        }
      : undefined,
  },
});

// Valore di `server` letto importando il file con Node 24 e Vite 8.3.8 (due esecuzioni identiche):
// senza TAURI_DEV_HOST: {"host":false,"port":1420,"strictPort":true}
// con TAURI_DEV_HOST=192.168.1.20: {"host":"192.168.1.20","port":1420,"strictPort":true,"hmr":{"protocol":"ws","host":"192.168.1.20","port":1421}}

È la configurazione proposta dalla guida. host: host || false lascia il server chiuso alla rete quando la variabile non c'è, e lo apre sull'indirizzo indicato quando c'è; hmr instrada anche il canale di ricarica a caldo sulla stessa rete. Importandola due volte, con e senza variabile, il valore di server è quello mostrato nei commenti. Il progetto creato con create-tauri-app arriva già così; con un altro server di sviluppo, Angular compreso, vale lo stesso principio (ascoltare sull'indirizzo di TAURI_DEV_HOST) da applicare con le opzioni di quel server. Per fare il debug serve l'ispettore: Safari su iOS, mentre su Android si apre chrome://inspect in Chrome.

Configurazione e permessi specifici del telefono

Alcune chiavi di tauri.conf.json esistono solo per il mobile, e le capability hanno un campo per scegliere la piattaforma.

Chiavi mobile in tauri.conf.json
{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "Appunti",
  "version": "1.2.3",
  "identifier": "dev.example.appunti",
  "build": {
    "devUrl": "http://localhost:1420",
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build",
    "frontendDist": "../dist"
  },
  "bundle": {
    "active": true,
    "android": { "minSdkVersion": 24 },
    "iOS": { "minimumSystemVersion": "15.0", "developmentTeam": "ABCDE12345" }
  }
}

bundle.android.minSdkVersion è il livello minimo di API Android: se il telefono ha un livello inferiore il sistema impedisce l'installazione, e il valore predefinito è 24. bundle.iOS.minimumSystemVersion vale "15.0" se non lo scrivi. developmentTeam è obbligatorio per lo sviluppo iOS perché la firma è imposta, e si può sovrascrivere con la variabile APPLE_DEVELOPMENT_TEAM. Per Google Play il numero di versione (versionCode) è ricavato dalla versione dell'app con la formula maggiore per un milione più minore per mille più patch: con 1.2.3 diventa 1002003. Puoi sostituirlo in bundle.android.versionCode se vuoi codici sequenziali. Il file è valido contro lo schema 2.12.5.

Capability valida solo su Android e iOS
{
  "$schema": "../gen/schemas/mobile-schema.json",
  "identifier": "mobile-capability",
  "description": "Permessi disponibili solo su telefono",
  "windows": ["main"],
  "platforms": ["iOS", "android"],
  "permissions": [
    "biometric:allow-authenticate",
    "barcode-scanner:allow-scan"
  ]
}

Il campo platforms limita la capability ai bersagli indicati; senza di esso vale per tutti. È il modo previsto per abilitare permessi di plugin che esistono solo sul telefono, come la biometria o la lettura di codici a barre: su desktop quei plugin non sono disponibili. È la divisione che usa la guida delle capability stessa, con un file per il desktop e uno per il mobile.

Che cosa copre il catalogo dei plugin sul telefono

È il punto che decide la fattibilità. Dalla tabella ufficiale dei plugin (README del repository, letta il 2026-11-13) ricavo questa corrispondenza fra bisogno e plugin; la classificazione completa è nell' articolo sui plugin.

BisognoPlugin ufficialePiattaforme dichiarate
Leggere codici a barre e QR con la fotocamerabarcode-scannersolo iOS e Android
Autenticazione biometricabiometricsolo iOS e Android
Posizione del dispositivogeolocationsolo iOS e Android
Vibrazione e feedback apticohapticssolo iOS e Android
Lettura e scrittura di tag NFCnfcsolo iOS e Android
Torciatorchsolo iOS e Android
Notifiche, dialoghi, appunti, apertura di link e filenotification, dialog, clipboard-manager, openerdesktop e mobile
Dati localistore, sqldesktop e mobile
File systemfsmobile non dichiarato
Aggiornamento dentro l'appupdatersolo desktop
Scattare una fotonessuno nella tabella-

La tabella dice due cose. Primo, per le funzioni da telefono più comuni (biometria, posizione, NFC, codici a barre) esiste un plugin ufficiale; secondo, mancano a catalogo funzioni che si danno per scontate, come scattare una foto, e il file system sul mobile non è dichiarato. Dove manca un plugin hai tre strade: usare un plugin della comunità dopo i controlli visti nell'articolo sui plugin, scrivere un plugin nativo tuo, oppure rinunciare alla funzione.

Quando serve codice nativo: un plugin in Kotlin

Un plugin può includere una libreria Android in Kotlin (o Java) e un pacchetto Swift per iOS. Il modello è quello del desktop: il frontend chiama un comando, la parte Rust del plugin lo inoltra al codice nativo e restituisce il risultato.

Un comando nativo Android (schema dalla guida, non compilato)
// android/src/main/java/ExamplePlugin.kt (importazioni omesse, come nella guida)
@TauriPlugin
class ExamplePlugin(private val activity: Activity): Plugin(activity) {
  @Command
  fun openCamera(invoke: Invoke) {
    val ret = JSObject()
    ret.put("path", "/path/to/photo.jpg")
    invoke.resolve(ret)
  }
}

La classe estende Plugin ed è annotata con @TauriPlugin; ogni metodo annotato con @Command può essere chiamato da Rust o da JavaScript. Il metodo riceve un oggetto Invoke e risponde con invoke.resolve. Il percorso /path/to/photo.jpg è un segnaposto della guida, non un'implementazione: la fotocamera vera va scritta. Per iOS la guida prevede una classe Swift con funzioni @objc che prendono un parametro Invoke. Il modello di permessi resta quello delle capability, e i progetti si creano con la CLI di plugin (plugin android init e plugin ios init) o con le opzioni --android e --ios alla creazione.

Distribuzione: Google Play e App Store

Il pacchetto per Google Play è l'Android App Bundle (AAB); l'APK serve per prove o per distribuire fuori dallo store. Per iOS la build produce un file IPA per App Store Connect, che poi si carica con Apple.

Pacchetti per gli store (schema da adattare, non eseguito)
# Android: pacchetto per Google Play (AAB) e APK per prove o distribuzione fuori dallo store
npm run tauri android build -- --aab
npm run tauri android build -- --apk --target aarch64

# iOS (solo macOS): pacchetto IPA per App Store Connect, poi caricamento con altool
npm run tauri ios build -- --export-method app-store-connect
xcrun altool --upload-app --type ios \
  --file "src-tauri/gen/apple/build/arm64/Appunti.ipa" \
  --apiKey "$APPLE_API_KEY_ID" --apiIssuer "$APPLE_API_ISSUER"

Senza --target, Tauri costruisce per tutte le architetture Android supportate (aarch64, armv7, i686, x86_64); indicarne una sola accorcia la build e produce un pacchetto utile per un test su un dispositivo noto. Su iOS il valore app-store-connect di --export-method prepara l'IPA per l'App Store, mentre release-testing la prepara per TestFlight. La guida usa altool con una chiave API di App Store Connect per il caricamento: è lo stesso nome del vecchio strumento di notarizzazione, ma qui indica il caricamento nello store, ed è l'uso previsto dalla documentazione di Tauri. Servono l'iscrizione ai rispettivi programmi sviluppatori, la firma del codice e l'app registrata sullo store; per iOS l'identificativo dell'app registrata deve coincidere con identifier in tauri.conf.json.

In integrazione continua, tauri-action ha un input mobile che la sua documentazione definisce sperimentale: sostituisce il comando di build con quello Android o iOS, ma non carica l'app sugli store e non installa Xcode o gli SDK al posto tuo. L'annuncio della 2.0 del 2024 diceva che l'azione non supportava ancora il mobile: lo stato di oggi è quindi cambiato, con la cautela del termine «experimental». L'updater non è disponibile su telefono, quindi gli aggiornamenti passano dagli store.

Quando conviene e quando no

Questi sono i criteri che pesano, senza una gerarchia:

  • Hai già un core Rust e un'interfaccia web che vuoi riutilizzare su desktop e telefono.
  • Le funzioni native che servono hanno un plugin nella tabella, o sei pronto a scrivere Kotlin e Swift.
  • Accetti la WebView di sistema come motore di rendering, con le differenze che comporta fra dispositivi.
  • Non hai bisogno dell'aggiornamento in app, perché sul telefono passa dagli store.
  • Hai un Mac se la destinazione include iOS.

Se uno dei punti salta, il resto non compensa: un'app che dipende dalla fotocamera o da API native non coperte ti obbliga a scrivere il codice nativo che speravi di evitare, e senza un Mac iOS resta fuori. Non ho confrontato Tauri con Flutter o React Native per dimensioni o prestazioni, perché non ho misure mie e non ne cito di altrui; il confronto che serve è quello su un prototipo della tua app, sullo stesso dispositivo.

Sul futuro: nella documentazione che ho letto non c'è una roadmap con date. L'annuncio del 2024 indicava come priorità l'esperienza di sviluppo mobile, e sul registro dei crate la serie 3 di tauri è in alpha (3.0.0-alpha.6, pubblicata il 2026-11-06): sono fatti, non promesse.

Domande frequenti

Tauri mobile è stabile?

Il supporto mobile fa parte della versione 2.0 stabile del 2 ottobre 2024. Parti singole sono più giovani: l'input mobile di tauri-action è sperimentale, e diversi plugin dichiarano il mobile come non provato. Valuta la stabilità funzione per funzione sul tuo prototipo.

Posso sviluppare per iOS da Linux o Windows?

No. La documentazione dei prerequisiti dice che lo sviluppo iOS richiede Xcode ed è disponibile solo su macOS. Android invece si sviluppa su tutti e tre i sistemi.

Quali versioni minime di Android e iOS supporta?

I valori predefiniti del riferimento di configurazione sono API 24 per Android (minSdkVersion) e iOS 15.0 (minimumSystemVersion); puoi cambiarli in tauri.conf.json.

Riuso il codice Rust del desktop senza modifiche?

La logica sì, purché non dipenda da plugin o API solo desktop. Dove serve un comportamento diverso usi cfg nel Rust e capability con platforms nella configurazione. La distribuzione, invece, è un lavoro a parte per ciascuno store.

Che cosa sai fare adesso

Sai che Tauri 2 include Android e iOS, come si prepara l'ambiente e come si avviano progetto e simulatore, quali chiavi di configurazione e di capability sono specifiche del telefono, e che cosa copre il catalogo dei plugin. Sai che i pacchetti per gli store si producono con tauri android build --aab e tauri ios build --export-method app-store-connect, e che aggiornamenti e CI hanno limiti dichiarati. Il passo successivo non è teorico: costruisci un prototipo con la funzione più rischiosa della tua app e misura lì ciò che qui ho solo letto.

Fonti

La configurazione di Vite è stata importata ed eseguita con Node 24.11 e Vite 8.3.8 (due esecuzioni identiche) e controllata con tsc; tauri.conf.json è stato validato contro lo schema di Tauri 2.12.5 e i file di capability sono stati letti come JSON. Tutto il resto è uno schema da adattare, non compilato né eseguito: nessuna app mobile è stata costruita, perché sulla macchina di scrittura non ci sono Rust, Android SDK né Xcode.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti